我正在使用C ++。使用Visual Studio 2010的C ++ 0x是正确的。
假设我有一个Z类。为了让我的应用程序更安全地使用指向这个类的指针,我可以一直使用智能指针(共享指针,弱指针)。
现在这个类Z继承自类X.我的应用程序的某些部分将使用指向类X的指针,其他部分将使用指向类Z的指针。
std::shared_ptr<X>
还是std::shared_ptr<Z>
)是否会删除实例?我确定如果删除std::shared_ptr<X>
,只要还有另一个std::shared_ptr<Y>
,该实例就会保留吗?现在假设我使用多重继承,其中Z继承自类X和Y.
我的应用程序的某些部分适用于std::shared_ptr<X>
,其他部分适用std::shared_ptr<Y>
,其他部分适用std::shared_ptr<Z>
。
顺便说一句,我怎样才能安全地将一个智能指针投射到另一个智能指针,例如将std::shared_ptr<Z>
投射到std::shared_ptr<X>
?这有用吗?这是允许的吗?
请注意,我明确地引用了非侵入式指针(作为C ++ 0x中的新std::shared_ptr
和std::weak_ptr
)。当使用侵入式指针(如Boost)时,它可能有效,因为实例本身负责保留计数器。
答案 0 :(得分:6)
是的,标准§20.9.11.2.10[util.smartptr.shared.cast]支持这一点。
您需要的工具是:
std::static_pointer_cast<>()
std::dynamic_pointer_cast<>()
它们与C ++ 03计数器部分static_cast<>()
和dynamic_cast<>()
具有相同的语义。一个区别是它们只适用于std::shared_ptr
s。只是为了详细,他们按照您的期望行事并正确地分享原始shared_ptr
之间的引用计数。
struct X { virtual ~X(){} };
struct Y : public X {};
struct Z : public X {};
int main()
{
{
//C++03
X* x = new Z;
Z* z = dynamic_cast<Z*>(x);
assert(z);
x = new Y;
z = dynamic_cast<Z*>(x);
assert(!z);
z = static_cast<Z*>(x);
assert(z); //EVIL!!!
}
{
//C++0x
std::shared_ptr<X> x{new Z};
std::shared_ptr<Z> z{std::dynamic_pointer_cast<Z>(x)};
assert(z);
x = std::make_shared<Y>();
z = std::dynamic_pointer_cast<Z>(x);
assert(!z);
z = std::static_pointer_cast<Z>(x);
assert(z); //EVIL!!!
// reference counts work as expected.
std::shared_ptr<Y> y{std::static_pointer_cast<Y>(x)};
assert(y);
std::weak_ptr<Y> w{y};
assert(w.expired());
y.reset();
assert(w.expired());
x.reset();
assert(!w.expired());
}
{
//s'more nice shared_ptr features
auto z = std::make_shared<X>();
std::shared_ptr<X> x{z};
assert( z == x );
x = z; //assignment also works.
}
}