以下方法是否合适?
class TA { };
class TB : TA { };
std::shared_ptr<TA> spta;
spta.reset(new TB);
答案 0 :(得分:3)
显示的代码存在一个问题,TB
必须从TA
公开继承。您有一个shared_ptr<TA>
,因此要存储在其中的指针必须可以转换为TA
,但是private
继承,基数是不可访问的,因此您的代码将无法编译。
class TA { };
class TB : public TA { };
除此之外,代码没有错误并且表现良好。通常,当您通过基类指针执行派生类实例的多态删除时,您需要基类&#39;析构函数为virtual
,因此调用派生类析构函数,但在shared_ptr
的情况下,这不是必需的。 shared_ptr::reset
是一个函数模板,它接受任何可转换为托管指针类型的Y*
。 shared_ptr
constructor template {/ 3}}也是如此。
话虽如此,你应该更喜欢制作基础课程。析构函数virtual
,特别是如果涉及的类具有其他virtual
函数。
答案 1 :(得分:2)
不,TA
不是私有的。
此外,正如评论中所建议的,基类的析构函数应该是虚拟。这通常是一种很好的做法,因为你不能保证你的类的实例只能用于共享指针。
要使其正常工作,您必须至少修改这些行:
class TA { };
class TB : TA { };
如下:
class TA { virtual ~TA() { } };
class TB : public TA { };
那些好,因为以下示例 good :
class TA { virtual ~TA() { } };
class TB : public TA { };
TA *spta = nullptr;
spta = new TB;
这主要取决于 good 对你意味着什么。这至少是合法的。
答案 2 :(得分:0)
这不是问题的答案,它试图澄清有关shared_ptr看似神奇的能力以避免使用虚拟析构函数的任何混淆。
这是一个小小的演示程序:
#include <iostream>
#include <memory>
struct A {
~A() { std::cout << __func__ << std::endl; }
void foo() { do_foo(); }
protected:
virtual void do_foo() {
std::cout << "A::" << __func__ << std::endl;
}
};
struct B : A {
~B() { std::cout << __func__ << std::endl; }
virtual void do_foo() override {
std::cout << "B::" << __func__ << " ";
A::do_foo();
}
};
using namespace std;
auto main() -> int
{
std::shared_ptr<A> p = std::make_shared<A>();
p->foo();
p = std::make_unique<B>();
p->foo();
cout << "deleting B:" << endl;
return 0;
}
预期产出:
A::do_foo
~A
B::do_foo A::do_foo
deleting B:
~B
~A
请注意,当在main()的末尾销毁B时,会调用正确的析构函数。