不显式初始化父类的虚拟继承

Virtual Inheritance without Explicitly Initializing a Parent Class

本文关键字:虚拟 继承 父类 初始化      更新时间:2023-10-16

我有两个类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的实例。对于这样一个对象,必须有一种方法来正确初始化MachineAtom部分。

Atom的初始化方式取决于创建的是HumanMachine还是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()