基类对象的C++向量

C++ vector of base class objects

本文关键字:向量 C++ 对象 基类      更新时间:2023-10-16

如果我有一个基类和一个派生类,如果我想在一个容器中将多个基类和/或派生类组合在一起,我可以创建一个基类指针向量。

示例:

class base
{
}
class derived : public base
{
}
std::vector<base*> group;

但有可能做到以下几点吗?

std::vector<base> group;

即:没有指针,哪个需要newing和deleteing?

编辑:2015年我还不知道多态性,如果你在2022年读到这个问题,那么值得搜索一些关于多态性的信息。

是的,您可以使用vector<base>&编译器不会为此用途引发任何错误。然而,vector<base>的问题在于它未能实现polymorphism。见下文:-

#include <iostream>
#include <vector>
using namespace std;
class base
{
    int x, id;
    static int i;
    public:
    base()
    {
        id = ++i;
        cout << "Base constructed: " << id << "n";
    }
    base (const base &b)
    {
        id = ++i;
        cout << "Base copy constructed: " << id << "n";
    }
    virtual int& getx()
    {
        cout << "Base getx() calledn";
        return x;
    }
    virtual ~base()
    {
        cout << "Base destroyed: " << id << "n";
    }
};
int base :: i = 0; 
class derived : public base
{
    int x, id;
    static int j;
    public:
    derived()
    {
        id = ++j;
        cout << "Derived constructed: " << id << "n";
    }
    derived (const derived& d)
    {
        id = ++j;
        cout << "Derived copy constructed: " << id << "n";
    }
    virtual int& getx()
    {
        cout << "Derived getx() calledn";
        return x;
    }
    virtual ~derived()
    {
        cout << "Derived destroyed: " << id << "n";
    }
};
int derived :: j = 0;
int main()
{
    vector<base> v;
    v.emplace_back(derived());
    v[0].getx() = 7;
    cout << "nn";
    for (int i=0; i<v.size(); ++i)
    cout << v[i].getx() <<"n";
    cout << "nn";
    return 0;
}
/* Output :-
Base constructed: 1
Derived constructed: 1
Base copy constructed: 2
Derived destroyed: 1
Base destroyed: 1
Base getx() called

Base getx() called
7

Base destroyed: 2
*/

您可以清楚地看到,虽然对象是derived,但既没有调用derivedcopy constructor,也没有调用相同的getx()。因此,用CCD_ 10实现多态性的目的就落空了。因此,您永远不应该使用vector<base>&更优选CCD_ 13中的CCD_。

您不能执行vector<base>,但可以执行vector<unique_ptr<base>>,从而避免手动写入新内容或删除内容。使用make_unique而不是new,并自动处理删除。