C++ boost::scoped_ptr 的析构函数问题
我对以下代码有疑问:
#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;
}
它创建以下输出:
1
A()
2
3
如您所见,它不会调用 A 的析构函数。 我认为调用 A 的析构函数的唯一方法是为 Interface 类添加一个析构函数,如下所示:
virtual ~Interface() { }
但我真的想避免在 Interface 类中使用任何实现,并且 virtual ~Interface() = 0; 不起作用(产生一些链接器错误,抱怨 ~Interface()
的实现不存在。
所以我的问题是:我必须更改什么才能使析构函数成为调用,但(如果可能)将接口保留为接口(仅抽象方法)。
I have a question about the following code:
#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;
}
It creates the following output:
1
A()
2
3
As you can see, it doesn't call the destructor of A.
The only way I see to get the destructor of A being called, is to add a destructor for the Interface class like this:
virtual ~Interface() { }
But I really want to avoid any Implementation in my Interface class and virtual ~Interface() = 0;
doesn't work (produces some linker errors complaining about a non existing implementation of ~Interface()
.
So my question is: What do I have to change in order to make the destructor being called, but (if possible) leave the Interface as an Interface (only abstract methods).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您必须在基类中定义虚拟析构函数,否则您将无法获得多态行为。
更重要的是,否则你会得到未定义的行为; §5.3.5/3:
强调我的。
我认为最好的是这个:
编译器可以轻松内联它,这与实现驻留在源文件中的解决方案不同。 (说到这里,这个解决方案甚至不要求你有一个。)它也让类成为纯虚拟的。
You must define a virtual destructor in the base class, otherwise you'll get no polymorphic behavior.
And more importantly, you get undefined behavior otherwise; §5.3.5/3:
Emphasis mine.
I'd argue the best is this one:
The compiler can easily inline this, unlike a solution where the implementation resides in a source file. (Speaking of which, this solution doesn't even mandate you have one.) It also leaves the class pure virtual.
您需要定义 Interface 析构函数的纯虚拟版本,但还需要定义析构函数的主体。这是 C++ 中的一种奇怪情况,即使函数是虚拟的,也必须定义它,因为在调用 A 析构函数之后,也会调用 Instance 析构函数。
因此,正确的答案是:
然后,在 cpp 文件中:
You need to define a pure virtual version of the Interface destructor, but you need to also define the body of the destructor. This is a sort of weird case in C++ where even though the function is virtual it must be defined because after the A destructor is called, the Instance destructor will also be called.
Thus the correct answer is:
And later, in a cpp file:
如果您想通过指向基类接口类型的指针删除派生类对象,则必须声明析构函数
virtual
,并且该析构函数必须具有实现。不过,您仍然可以将其声明为纯虚拟:
You must declare the destructor
virtual
if you want to delete derived-class objects via a pointer to your base class interface type, and that destructor must have an implementation.You may still declare it pure virtual, though: