boost :: scoped_ptr的C++析构函数问题

bb-*_*ion 2 c++ abstract-class destructor virtual-functions

我对以下代码有疑问:

#include <iostream>
#include <boost/scoped_ptr.hpp>

class Interface
{
};

class A : public Interface
{
    public:
        A() { std::cout << "A()" << std::endl; }
        virtual ~A() { std::cout << "~A()" << std::endl; }
};


Interface* get_a()
{
    A* a = new A;
    return a;
}

int main()
{
    {
        std::cout << "1" << std::endl;
        boost::scoped_ptr<Interface> x(get_a());
        std::cout << "2" << std::endl;
    }
    std::cout << "3" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

它创建以下输出:

1
A()
2
3
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,它不会调用A的析构函数.我看到获取A的析构函数的唯一方法是为Interface类添加一个析构函数,如下所示:

virtual ~Interface() { }
Run Code Online (Sandbox Code Playgroud)

但我真的想避免在我的接口类中的任何实现并且virtual ~Interface() = 0;不起作用(产生一些链接器错误抱怨不存在的实现~Interface().

所以我的问题是:为了使析构函数被调用,我需要更改什么,但是(如果可能的话)将接口保留为接口(仅限抽象方法).

GMa*_*ckG 5

您必须在基类中定义虚拟析构函数,否则您将不会获得多态行为.

更重要的是,否则会得到未定义的行为; §5.3.5/ 3:

如果操作数的静态类型与其动态类型不同,则静态类型应为操作数的动态类型的基类,静态类型应具有虚拟析构函数或行为未定义.

强调我的.


我认为最好的是这一个:

class Interface
{
public:
    virtual ~Interface(void) = 0;
};

inline Interface::~Interface(void) {}
Run Code Online (Sandbox Code Playgroud)

与实现驻留在源文件中的解决方案不同,编译器可以轻松地对此进行内联.(说到这个,这个解决方案甚至不会要求你有一个.)它也让这个类纯粹是虚拟的.