3

下面的代码,打印出来

Derived
Base
Base

但是我需要将每个派生对象放入 User::items 中,调用它自己的打印函数,而不是基类。我可以在不使用指针的情况下实现这一点吗?如果不可能的话,我应该如何编写一个一个删除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();
}
4

3 回答 3

5

你需要使用指针,你需要给你的基类一个虚拟析构函数。析构函数不必做任何事情,但它必须存在。您的 add 函数如下所示:

void add_item( Base * item ){
    item->print();
    items.push_back( item );
}

其中项目是一个vector<Base *>。要销毁项目(假设是虚拟析构函数):

for( int i = 0; i < items.size(); i++ ) {
    delete items[i];
}
items.clear();
于 2010-04-04T17:44:52.447 回答
1

您需要一个用于 base 的虚拟析构函数,以确保在对 typeDerived的指针调用 delete 时正确销毁type 的对象Base

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

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

然后,您可以使用 Boosts ptr_vector存储指向您的对象的指针,这些对象会在容器被销毁时被删除。

于 2010-04-04T17:48:29.567 回答
0

只是解释:

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

于 2010-04-08T08:44:17.150 回答