共享的空指针。为什么这样做? [英] Shared void pointers. Why does this work?

查看:125
本文介绍了共享的空指针。为什么这样做?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要解决我的应用程序中一个非常特殊的问题,我需要一个共享指针来分配数据,但对于外部世界,底层数据类型应保持隐藏。

To solve a very peculiar problem in my application I need a shared-pointer to allocated data, but to the outside world, the underlying data type should remain hidden.

我可以通过创建某种我所有其他类都可以继承的Root类来解决此问题,并在此Root类上使用shared_ptr,如下所示:

I could solve this by making some kind of Root class of which all my other classes inherit, and use a shared_ptr on this Root class, like this:

std::shared_ptr<Root>

但是:


  • 我不希望我的所有类都可以从这个Root类继承而来,只是要具有这个共享的指针

  • 有时我想返回一个共享指针到std :: vector ,或std :: list或std :: set ...显然不是从我的Root类继承的

奇怪足够,似乎您可以在void上创建一个shared_ptr,并且似乎可以正常工作,如以下示例所示:

Strange enough, it seems that you can create a shared_ptr on void and this seems to work correctly, like shown in this example:

class X
   {
   public:
      X() {std::cout << "X::ctor" << std::endl;}
      virtual ~X() {std::cout << "X::dtor" << std::endl;}
   };

typedef std::shared_ptr<void> SharedVoidPointer;

int main()
{
X *x = new X();
SharedVoidPointer sp1(x);
}

x已正确删除,在更大的实验中,我可以验证共享指针确实确实做了它需要做的事情(在最后一个shared_ptr之后删除x)。

x is correctly deleted and in a larger experiment I could verify that the shared pointer does indeed what it needs to do (delete x afer the last shared_ptr turns out the light).

当然,这可以解决我的问题,因为我现在可以使用SharedVoidPointer数据成员,并确保已正确清理它应该在的位置。

Of course this solves my problem, since I can now return data with a SharedVoidPointer data member and be sure that it's correctly cleaned up where it should be.

但这是否可以保证在所有情况下都能正常工作?它显然可以在Visual Studio 2010中运行,但是在其他编译器上也可以正常运行吗?在其他平台上?

But is this guaranteed to work in all cases? It clearly works in Visual Studio 2010, but does this also work correctly on other compilers? On other platforms?

推荐答案

您使用的 shared_ptr 构造函数实际上是构造器模板,如下所示:

The shared_ptr constructor that you use is actually a constructor template that looks like:

template <typename U>
shared_ptr(U* p) { }

它知道构造函数中的实际值指针的类型是( X ),并使用此信息来创建函子,该函子可以正确地删除指针并确保正确的析构函数被调用。此函子(称为 shared_ptr 的删除程序)通常与用于维护对象共享所有权的引用计数一起存储。

It knows inside of the constructor what the actual type of the pointer is (X) and uses this information to create a functor that can correctly delete the pointer and ensure the correct destructor is called. This functor (called the shared_ptr's "deleter") is usually stored alongside the reference counts used to maintain shared ownership of the object.

请注意,仅当您将正确类型的指针传递给 shared_ptr 构造函数时,此方法才有效。如果您改为说:

Note that this only works if you pass a pointer of the correct type to the shared_ptr constructor. If you had instead said:

SharedVoidPointer sp1(static_cast<void*>(x));

然后这将不起作用,因为在构造函数模板 U 将为 void ,而不是 X 。这样的行为将是不确定的,因为不允许使用空指针调用 delete

then this would not have worked because in the constructor template, U would be void, not X. The behavior would then have been undefined, because you aren't allowed to call delete with a void pointer.

通常,如果始终在构造 shared_ptr 的过程中始终调用 new 并且不要将创建内容分开,则会很安全。从对象的所有权( shared_ptr 的创建)中删除对象( new )。

In general, you are safe if you always call new in the construction of a shared_ptr and don't separate the creation of the object (the new) from the taking of ownership of the object (the creation of the shared_ptr).

这篇关于共享的空指针。为什么这样做?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆