【发布时间】:2011-06-15 23:46:06
【问题描述】:
为了解决我的应用程序中一个非常特殊的问题,我需要一个指向已分配数据的共享指针,但对于外部世界,底层数据类型应该保持隐藏。
我可以通过创建我所有其他类都继承的某种 Root 类来解决这个问题,并在这个 Root 类上使用 shared_ptr,如下所示:
std::shared_ptr<Root>
但是:
- 我不希望我的所有类都从这个 Root 类继承,只是为了能够拥有这个共享指针
- 有时我想返回一个指向 std::vector 或 std::list 或 std::set 的共享指针...这显然不是从我的 Root 类继承的
很奇怪,您似乎可以在 void 上创建一个 shared_ptr 并且这似乎可以正常工作,如下例所示:
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)。
这当然解决了我的问题,因为我现在可以使用 SharedVoidPointer 数据成员返回数据,并确保它在应有的位置被正确清理。
但这能保证在所有情况下都有效吗?它在 Visual Studio 2010 中显然可以工作,但是这在其他编译器上也能正常工作吗?在其他平台上?
【问题讨论】:
-
@Charles,这个问题看起来很相似,但在我的问题中,我明确要求避免使用 void 指针(不是指向基类的指针),以及这是否由标准保证(而不是为什么它适用于提升)。
-
@Patrick:这完全是同一个问题。删除器是在智能指针取得指针所有权时构造的,此时你传入的指针的静态类型信息用于创建删除器。
-
难道没有隐藏的第二个假设吗?那个问题是关于
shared_ptr<Base>;这个关于shared_ptr<void>。据推测,这两种方法都有效,因为存在从Derived*到Base*和void*的隐式转换。因此,答案的一个重要部分必须是每个(非函数)指针类型都隐式转换为void*。我怀疑这不是真的。const void*没有。 -
@Patrick:错了。实际上,您可以删除 const 指针和指向 const 对象的指针。
标签: c++ visual-c++ c++11 shared-ptr smart-pointers