在C++中初始化抽象基类的子类数组

Initializing array of subclasses of abstract base class in C++

本文关键字:子类 数组 基类 抽象 C++ 初始化      更新时间:2023-10-16

我在C++中有一个抽象基类,需要创建一个数组来存储作为其子类的对象。我使用指向子类的指针,因为数组的每个成员都需要具有相同的大小。目前我正在声明和初始化我的数组,如下所示:

BaseClass *array[];
...
array =
{
    &SubClass1(...),
    &SubClass2(...),
    ...
    &SubClass3(...)
};

当我尝试编译时,这给了我以下信息:

warning: taking address of temporary
error: too many initializers for ‘BaseClass* [0]’

做这件事的正确方法是什么?

您不能用临时存储来实现这一点——您应该静态、动态地分配对象,或者将它们放入自动存储中。

要静态分配对象,请执行以下操作:

static SubClass1 s1(..);
static SubClass2 s2(..);
static SubClass3 s3(..);
BaseClass *array [] = { &s1, &s2, &s3 };

如果您动态分配它们,请考虑使用vector<shared_ptr<T>>而不是"原始"指针来自动解除分配:

vector<shared_ptr<BaseClass>> data = {
    make_shared<SubClass1>(...)
,   make_shared<SubClass2>(...)
,   make_shared<SubClass3>(...)
};

在同一行,并且不像在&SubClass1(...),中那样使用临时的地址。比如:

BaseClass *array [] = { new SubClass(...), new SubClass2(...), .... };

但这种设计闻起来有点像不知道如何做工厂。

由于您没有使用std::shared_ptrstd::unique_ptr来管理指针,请不要忘记delete它们!(感谢@dasblinkenlight)

那些SubClass1(...)是临时对象,如果控件超出范围,它们将被销毁,并且array的所有指针都将是指向无效地址的悬挂指针。

您可以在array的作用域中创建这些对象,以确保这些对象和该数组具有相同的生存期:

SubClass1 class1 (...);
SubClass2 class2 (...);
SubClass3 class3 (...);
BaseClass *array[] =
{
    &class1(...),
    &class2(...),
    ...
};

也可以使用智能指针:

std::unique_ptr<BaseClass> array[] =
{
    std::unique_ptr<BaseClass>(new SubClass1),
    std::unique_ptr<BaseClass>(new SubClass2)
};