C++ 存储在ptr_向量中的派生类未被破坏
正在试图找到使用ptr_向量存储、访问和释放对象的最佳方法,特别是当存储的对象从其他对象继承时(ptr_向量不应该有任何对象切片问题)。 但是当运行下面的程序时,令人惊讶的是派生类没有被破坏。有人知道为什么吗C++ 存储在ptr_向量中的派生类未被破坏,c++,boost,ptr-vector,C++,Boost,Ptr Vector,正在试图找到使用ptr_向量存储、访问和释放对象的最佳方法,特别是当存储的对象从其他对象继承时(ptr_向量不应该有任何对象切片问题)。 但是当运行下面的程序时,令人惊讶的是派生类没有被破坏。有人知道为什么吗 #include <boost/ptr_container/ptr_vector.hpp> #include <iostream> #include <boost/ptr_container/ptr_map.hpp> #include <boost
#include <boost/ptr_container/ptr_vector.hpp>
#include <iostream>
#include <boost/ptr_container/ptr_map.hpp>
#include <boost/foreach.hpp>
using namespace std;
class A
{
public:
int id;
A() {cout<<"Constructed A()"<<endl;}
A(int i):id(i) {cout<<"Constructed A"<<i<<endl;}
~A() {cout<<"* Destructed A"<<id<<endl;}
};
class B:public A
{
public:
int i;
B() {cout<<"Constructed B"<<endl;}
B(int ii):i(ii) {id=ii;cout<<"Constructed B"<<i<<endl;}
~B() {cout<<"* Destructed B"<<i<<endl;}
};
class zoo
{
boost::ptr_vector<A> the_animals;
public:
void addAnimal(A* a) {the_animals.push_back( a );}
void removeAnimal(int id) {the_animals.release(the_animals.begin()+id); }
void removeOwnership(int id) {the_animals.release(the_animals.begin()+id).release();}
};
int main()
{
zoo z;
z.addAnimal( new B(0) );
//delete abc;z.addAnimal(abc);//doing this will cause heap corruption
B* lion=new B(1);
z.addAnimal(lion);
z.removeOwnership(1);
delete lion;
z.removeAnimal(0);
}//main
为什么B0没有被破坏?对象被切片了吗?基类的析构函数不是虚拟的:
~A() {cout<<"* Destructed A"<<id<<endl;}
~A(){cout基类的析构函数不是虚拟的:
~A() {cout<<"* Destructed A"<<id<<endl;}
~A(){coutBut我根本没有使用虚拟函数。为什么析构函数应该是虚拟的?@Nav,请参阅以获得更详细的答案,但基本上,如果通过指向对象基类型的指针删除对象,则基本对象析构函数必须是虚拟的上帝!我完全错过了B被升级的要点。谢谢Samuel和Glen:)B没有升级这是多态性的一个非常简单的例子——您正在调用一个函数(析构函数)在指向基类a的指针类型的指针上。如果该函数不是虚函数,它不知道需要检查虚函数表并调用B中的重写析构函数。但我根本不使用虚函数。为什么析构函数应该是虚函数?@Nav,请参阅以获得更详细的答案,但基本上如果通过一个指向它的基类型的指针你的基对象析构函数必须是virtualOh god!我完全没有注意到B被上溯的点。感谢Samuel和Glen:)B没有被上溯。这是多态性的一个非常简单的例子-你在调用一个函数(析构函数)在指向基类a的指针类型的指针上。如果该函数不是虚函数,它不知道需要检查虚函数表并调用B中重写的析构函数。
virtual ~A() {cout<<"* Destructed A"<<id<<endl;}