纯虚函数和std::shared_ptr

6
可能是我在文档中遗漏了某些内容(或者只是无法进行正确的谷歌搜索),但我在使用shared_ptr和纯虚函数时遇到了问题。
下面是一个简短的可以工作的示例:
class Base
{
public:
    virtual int stuff() = 0;
};

class Derived : public Base
{
public:
    virtual int stuff() {return 6;}
};

class Container
{
public:
    Container() : m_x( 0 ) {}
    Container(Base* x) : m_x(x) {} 

private:
    Base* m_x;
};

因为我想使用新的高级 std::shared_ptr,所以我修改了Container如下:

class Container
{
public:
    Container() : m_x( std::make_shared<Base>() ) {}
    Container(const std::shared_ptr<Base>& x) : m_x(x) {} 

private:
    std::shared_ptr<Base> m_x;
};

显然,这并不起作用,clang和其他编译器会抱怨: 在Container() : m_x( std::make_shared<Base>() ) {} 行中,error: allocating an object of abstract class type 'Base'。所以问题来了:如何使用std :: shared_ptr使其工作?

1
默认的构造函数初始化程序不正确,也根本不应该存在。像任何指针一样,std::shared_ptr<> 可以包含 nullptr,并且在默认构造时会这样做。 - WhozCraig
2
基类的虚析构函数在哪里? - spin_eight
@spin_eight 很好的观点,但对于 shared_ptr 不是必需的。 - dyp
3个回答

8
您的问题出现在这里:

Container() : m_x( std::make_shared<Base>() ) {}

您不能创建Base对象。您需要的是一个空的shared_ptr。因此,请执行以下操作。
Container() : m_x( std::shared_ptr<Base>() ) {}

或者这样做。
Container() : m_x() {}

相等的意思是一样的。


是的...显然我需要一杯咖啡 :) 谢谢! - Ferenc Deak
1
或者简单地写成 Container() {} - WhozCraig

2

std::make_shared<Base>() 相当于 new Base()。你需要的是完全省略 m_x 的初始化(它将通过默认构造函数为空初始化),或者明确地进行初始化:

Container() : m_x(nullptr) {}

0

使用模板化构造函数直接构造对象。
因此,除非

  • B 变为非抽象类,
  • 您选择一个具体的优选派生类或
  • 您接受 0 初始化 m_x

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接