不显式初始化父类的虚拟继承
Virtual Inheritance without Explicitly Initializing a Parent Class
我有两个类Machine和Human,它们实际上继承自atom。现在我写了一个名为"Cyborg"的类,并希望从Cyborg初始化Atom。代码是
#include <iostream>
using namespace std;
class Atom {
public:
Atom(size_t t): transformium(t) {};
private:
const size_t transformium;
};
class Human : public virtual Atom {
public:
Human(string name) : Atom(-1), name(name) {}
protected:
string name;
};
class Machine : public virtual Atom {
public:
Machine() {}
Machine(int id) : id(id) {}
protected:
int id;
};
class Cyborg : public Human, public Machine {
public:
Cyborg(string name, int id) : Atom(0), Human(name) {}
};
int main() {
Cyborg cyborg("robocup", 911);
return 0;
}
但是,由于const成员transformium的存在,CXX编译器要求Machine初始化Atom。
error: constructor for 'Machine' must explicitly initialize the base class 'Atom' which does not have a default constructor
根据编译器错误提示,必须在Machine
的构造函数中显式初始化基类Atom
。
这样做的原因是您可以创建Machine
的实例。对于这样一个对象,必须有一种方法来正确初始化Machine
的Atom
部分。
Atom
的初始化方式取决于创建的是Human
、Machine
还是Cyborg
的实例。以下是您的代码的更新版本,并附带了一些解释。
#include <iostream>
using namespace std;
class Atom {
public:
Atom(size_t t): transformium(t) { std::cout << "Came to Atom::Atom()n"; }
private:
const size_t transformium;
};
class Human : public virtual Atom {
public:
Human(string name) : Atom(-1), name(name) {}
// Atom(-1) is ignored when an instance of Cyborg is created
// but not when an instance of Human is created.
protected:
string name;
};
class Machine : public virtual Atom {
public:
Machine(int id) : id(id), Atom(-1) {}
// Atom(-1) is ignored when an instance of Cyborg is created
// but not when an instance of Machine is created.
protected:
int id;
};
class Cyborg : public Human, public Machine {
public:
Cyborg(string name, int id) : Atom(0), Human(name), Machine(id) {}
// Atom needs to be intialized here since it won't be initialized
// in either Human or Machine.
};
int main() {
Cyborg cyborg("robocup", 911); // Calls Atom::Atom() only once.
std::cout << "------------------n";
Human human("robocup"); // Calls Atom::Atom() once.
std::cout << "------------------n";
Machine machine(911); // Calls Atom::Atom() once.
return 0;
}
输出:<>之前来到Atom::Atom()------------------来到Atom::Atom()------------------来到Atom::Atom() 相关文章:
- 大小虚拟继承中的派生类
- C++ 多级虚拟继承编译问题
- 如何正确获得虚拟继承?
- 避免C++虚拟继承
- 虚拟继承基构造函数消除
- 虚拟继承中是否存在多重继承?
- 了解虚拟继承类 vtables 和 vptr 创建
- 当键是虚拟继承中涉及的基类指针时,对 std::unordered_map 项的访问崩溃
- 我是否需要在虚拟继承类的构造函数中初始化基类以解决菱形继承问题?
- C++ 不明确访问 - 虚拟继承
- 虚拟继承中来自基数的虚拟调用
- 虚拟继承:调用没有匹配函数
- 虚拟继承的内部机制
- 联合虚拟继承
- C++虚拟继承类的大小
- C++虚拟继承、虚拟析构函数和 dynamic_cast<void*>
- 虚拟继承构造函数的组装
- 虚拟继承情况下类的意外大小
- 虚拟继承情况下的 vtable
- C++解决没有虚拟继承的钻石继承问题