是否可以在不修改父类的情况下将成员变量初始化推迟到继承的类?

Is it possible to defer member variable initialization to inherited class without modifying the parent class?

本文关键字:初始化 变量 推迟 迟到 继承 成员 情况下 修改 是否 父类      更新时间:2023-10-16

我遇到了一个特定的问题,我已将其转换为以下最小,完整和可验证的示例。

#include <iostream>
class Foo {
public:
Foo(int v) : val(v) {}
int get_val() const
{
return val;
}
private:
int val;
};
class Parent {
public:
Parent() : member(0) {}
const Foo& get_member() const
{
return member;
}
protected:
Foo member;
};
// Nothing above this line should be changed
class Child : public Parent
{
public:
// This doesn't work (compile error)
//Child() Parent::member(1) {}
// Nor does this (also a compile error)
//Child() this->member(1) {}
};
int main()
{
Child x;
std::cout << x.get_member().get_val() << std::endl;
return 0;
}

此示例演示了我在一个较大的软件项目中遇到的问题,在该项目中,我从外部库继承,但需要直接初始化父级的成员变量之一

遗憾的是,Parent 类没有参数化其成员初始化的构造函数。

如果Parent类具有窗体的构造函数

Parent(int val) : member(val) {}

然后我可以编写一个Child构造函数作为

Child() Parent::Parent(1) {}

但对我来说并非如此。

问题:是否可以将父级成员变量的初始化推迟到继承的类?如果是这样,如何?

是否可以将父级成员变量的初始化推迟到继承的类?如果是这样,如何?

父类的成员变量在其成员初始化列表或构造函数的主体中初始化。子类不能在其初始值设定项列表中初始化父类的成员变量 - 这是语言不允许的。您能做的最好的事情似乎是在子类的构造函数的主体中设置父类成员的值。

例:

struct foo
{
int a;
};
struct bar : foo
{
bar() : a(0) {} // Not allowed
};

struct bar : foo
{
bar() { a = 0; } // Allowed
};

最简单的方法是在Child类构造函数体中初始化Parent::member(再次(:

class Child : public Parent
{
public:
Child() {
Parent::member = 1;
}
};

观看现场演示。


正如评论中澄清的那样,您不应该分配Parent::member变量。

在这种情况下(让我们假设设计至少是有用的(, 您通常能够为父类成员实例的某些属性应用 setter:

class Foo {
Foo(const& Foo) = delete;
Foo& operator=(const& Foo) = delete;
public:
Foo() = default;
int property() const;
void property(int newVal);
};
class Parent {
protected:
Foo member;
public:
Parent() = default;
};
class Child : public Parent {
public:
Child() {
Parent::member.property(1);
};
};