是否可以在不修改父类的情况下将成员变量初始化推迟到继承类?
问题描述:
我遇到了一个特定的问题,我已将其转换为以下Minimal, Complete, and Verifiable example。是否可以在不修改父类的情况下将成员变量初始化推迟到继承类?
#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);
};
};
号的基类必须完全构造的派生类甚至开始构造之前。你不能只在派生类构造函数体中设置成员? – NathanOliver
@NathanOliver谢谢,不,我不能。父类使用默认参数化来初始化其成员,该默认参数化设置一些网络连接。这些参数在初始化后不能更改。 – jodag
那么如果没有办法设置基类成员,你希望如何设置它? – NathanOliver