C++多态性和切片

发布于 2024-08-27 11:14:14 字数 803 浏览 6 评论 0原文

下面的代码,打印出来

Derived
Base
Base

但是我需要将每个 Derived 对象放入 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();
}

The following code, prints out

Derived
Base
Base

But I need every Derived object put into User::items, call its own print function, but not the base class one. Can I achieve that without using pointers? If it is not possible, how should I write the function that deletes User::items one by one and frees memory, so that there should not be any memory leaks?

#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();
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

纸短情长 2024-09-03 11:14:14

您需要使用指针,并且需要为基类提供虚拟析构函数。析构函数不必做任何事情,但它必须存在。您的添加函数如下所示:

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

其中 items 是一个 vector。销毁项目(假设是虚拟析构函数):

for( int i = 0; i < items.size(); i++ ) {
    delete items[i];
}
items.clear();

You need to use pointers, and you need to give your base class a virtual destructor. The destructor does not have to do anything, but it must exist. Your add function then looks like:

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

where items is a vector<Base *>. To destroy the items (assuming a virtual destructor):

for( int i = 0; i < items.size(); i++ ) {
    delete items[i];
}
items.clear();
惜醉颜 2024-09-03 11:14:14

您需要为基类提供一个虚拟析构函数,以确保在对Base 类型的指针调用delete 时正确销毁Derived 类型的对象。

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

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

然后你可以使用Boosts ptr_vector来存储指向容器被销毁时被删除的对象的指针。

You need a virtual destructor for base to make sure objects of type Derived get destroyed properly when calling delete on a pointer of type Base.

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

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

Then you can use Boosts ptr_vector to store pointers to your objects that get deleted when the container gets destroyed.

眼波传意 2024-09-03 11:14:14

只是解释一下:

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

just explaining:

In order to understand what is going on, you may try to define class Base abstract (e.g. defining any method pure virtual). In this case I expect you'll see compiler errors.
This way you'll recognize what vector actually does: it creates new instances of class Base by means of copy construction when you push_back( derived ).
This is why you want to use pointers instead. Then vector works with your originally created objects of type Derived instead of own copies of type Base.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文