C++ C++;多态性与切片

C++ C++;多态性与切片,c++,polymorphism,object-slicing,C++,Polymorphism,Object Slicing,下面的代码,打印出来 Derived Base Base 但是我需要将每个派生对象放入User::items中,调用它自己的print函数,而不是基类函数。不使用指针我能做到吗?如果不可能,我应该如何编写一个接一个地删除User::items并释放内存的函数,以便不会出现任何内存泄漏 #include <iostream> #include <vector> #include <algorithm> using namespace std; class

下面的代码,打印出来

Derived
Base
Base
但是我需要将每个派生对象放入User::items中,调用它自己的print函数,而不是基类函数。不使用指针我能做到吗?如果不可能,我应该如何编写一个接一个地删除User::items并释放内存的函数,以便不会出现任何内存泄漏

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class Base{
public:
  virtual void print(){ cout << "Base" << endl;}
};

class Derived: public Base{
public:
  void print(){ cout << "Derived" << endl;}
};

class User{
public:
  vector<Base> items;
  void add_item( Base& item ){
    item.print();
    items.push_back( item );
    items.back().print();
  }
};

void fill_items( User& u ){
  Derived d;
  u.add_item( d );
}

int main(){
  User u;
  fill_items( u );
  u.items[0].print();
}
#包括
#包括
#包括
使用名称空间std;
阶级基础{
公众:

virtual void print(){cout您需要使用指针,并且需要为基类提供一个虚拟析构函数。析构函数不必执行任何操作,但它必须存在。然后,您的add函数看起来像:

void add_item( Base * item ){
    item->print();
    items.push_back( item );
}
其中items是一个
向量
。要销毁这些项(假设为虚拟析构函数):

for(int i=0;i
在对
base
类型的指针调用delete时,需要为base使用虚拟析构函数,以确保类型为
的对象正确销毁

class Base{
public:
  virtual void print(){ cout << "Base" << endl;}

  virtual ~Base( ) { }  // virtual destructor
};
类基{
公众:
virtual void print(){cout只是解释一下:

为了理解发生了什么,您可以尝试定义类基抽象(例如,定义任何纯虚拟的方法)。在这种情况下,我希望您会看到编译器错误。 通过这种方式,您将认识到vector的实际作用:当您向后推_(派生)时,它通过复制构造创建类Base的新实例。
这就是为什么您要使用指针。然后vector处理您最初创建的派生类型的对象,而不是自己的Base类型副本。

使用智能指针避免内存泄漏这并不能防止内存泄漏,它可以防止未定义的行为。对。添加了相关提示。请参阅我的第一条评论。未定义的行为!=内存泄漏。此外,对于那些学习C++的人来说,建议语义复杂的升压容器不是很有帮助。为了正确使用这些容器,首先必须了解C++的基本概念。@尼尔是否应该将虚拟析构函数存在,使其成为虚拟的?这样它会动态地破坏基础和派生类对象?@ Draco The破坏或者需要创建并定义为虚拟的,这样当通过基类指针删除对象时,销毁将遵循虚拟函数查找机制。析构函数会自动从子对象“链接”到基对象,但您必须首先调用子dtor!换句话说,对于非虚拟dtor,“删除项[i];”将只调用基类析构函数,而不是“实际派生的”析构函数。添加“virtual”将查找并调用正确的函数。(顺便说一句,您只需要基类析构函数上的virtual标记,并且不一定需要派生类的显式析构函数。)是的,我知道。那叫做切片。我只是想知道除了使用指针,还有其他机会吗。
class Base{
public:
  virtual void print(){ cout << "Base" << endl;}

  virtual ~Base( ) { }  // virtual destructor
};