英文:
sequence of destructors when using unique_ptr to base class
问题
我正在尝试使用std::unique_ptr
和类继承(即多态性)。我正在运行以下代码:
#include <iostream>
#include <memory>
class polygon {
public:
int side;
polygon(int i) : side(i) { std::cout << "polygon created" << std::endl; }
virtual int perimeter() = 0;
~polygon() { std::cout << "polygon destroyed" << std::endl; }
};
class triangle : public polygon {
public:
triangle(int i) : polygon::polygon{i} { std::cout << "triangle created" << std::endl; }
int perimeter() { return side * 3; }
~triangle() { std::cout << "triangle destroyed" << std::endl; }
};
class square : public polygon {
public:
square(int i) : polygon::polygon{i} { std::cout << "square created" << std::endl; }
int perimeter() { return side * 4; }
~square() { std::cout << "square destroyed" << std::endl; }
};
int main() {
std::unique_ptr<polygon> pp = std::make_unique<square>(5); // (1)
std::cout << pp->perimeter() << std::endl;
pp = std::make_unique<triangle>(4); // (2)
std::cout << pp->perimeter() << std::endl;
return 0;
}
我可以看到析构函数按与构造函数相反的顺序调用,这也适用于基类派生类构造函数和析构函数的顺序。
但是,只有polygon
的析构函数被调用,也就是在分配(我猜是因为第一个std::make_unique<square>
被销毁,或者当返回0时)。这是否意味着在销毁基类std::unique_ptr
时,分配给(1)和(2)中的派生类对象的内存会泄漏?
英文:
I am experimenting with std::unique_ptr
and class inheritance (i.e. polymorphism somehow). The code I am running is the following:
#include<iostream>
#include<memory>
class polygon {
public:
int side;
polygon(int i): side(i) {std::cout<<"polygon created"<<std::endl;}
virtual int perimeter() = 0;
~polygon() {std::cout<<"polygon destroyed"<<std::endl;}
};
class triangle : public polygon {
public:
triangle(int i): polygon::polygon{i} {std::cout<<"triangle created"<<std::endl;}
int perimeter() { return side*3; }
~triangle() {std::cout<<"triangle destroyed"<<std::endl;}
};
class square : public polygon {
public:
square(int i): polygon::polygon{i} {std::cout<<"square created"<<std::endl;}
int perimeter() { return side*4; }
~square() {std::cout<<"square destroyed"<<std::endl;}
};
int main() {
std::unique_ptr<polygon> pp = std::make_unique<square>(5); // (1)
std::cout << pp->perimeter() << std::endl;
pp = std::make_unique<triangle>(4); // (2)
std::cout << pp->perimeter() << std::endl;
return 0;
}
I can see that destructors are invoked in reverse order with respect to constructors, and that applies also to base class-derived class sequences of constructors and destructors.
However, only the polygon
destructors are invoked, i.e. when assigning (I guess because the first std::make_unique<square>
is destroyed, or when returning 0. Does that mean that when destroying a base class std::unique_ptr
, the memory allocated to the derived class objects in (1) and (2) is leaked?
答案1
得分: 5
是的,在C++中,如果你通过指向基类的指针删除对象(就像你所做的那样),你必须明确将基类的析构函数标记为virtual
。所以将polygon
的析构函数更改为:
virtual ~polygon() {std::cout << "polygon destroyed" << std::endl;}
附注:将你的perimeter
函数声明为const
。
英文:
Yes, in C++ you have to explicitly mark your destructor virtual
in the base class, if you delete through a pointer to the base class (as you do). So change the destructor of polygon
to:
virtual ~polygon() {std::cout<<"polygon destroyed"<<std::endl;}
PS: Make your perimeter
function const
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论