类的构造函数必须显式初始化基类



我得到了:

//all classes are in different files
namespace Tree {
class Node {
NodeType type;
protected:
std::string nodename;
Node(Node::NodeType _type) : type(_type) {}
};
}
class Parent : public virtual Tree::Node {
protected:
Parent() : Node(Node::UNDEFINED) {}
};
class Child: public virtual Tree::Node {
protected:
Child() : Node(Node::UNDEFINED) {}
};
namespace Tree {
class Element :
public Parent,
public Child,
public virtual Node {
protected:
Element() : Node(Node::ELEMENT) {}
};
}
class SpecificElement: public Tree::Element {
public:
SpecificElement(const std::string name) {
nodename = name;
}
};

SpecificElement的构造函数中出现错误:

"SpecificElement"的构造函数必须显式初始化基 类 'Tree::Node' 没有默认构造器

Node不应该通过Element初始化吗?,为什么编译器要求我在那里显式初始化?

我不知道这是否与被保护的建筑商有关。或者如果是用于命名空间,尽管我不这么认为,因为代码已编译,直到我引入了类SpecificElement.

我会在SpecificElement中调用 Node 的构造函数,但我有更多的类继承自此,并且都要求我显式初始化 Node,而我无法通过设计做到这一点。

编辑:感谢@r-sahu,我解决了如下

namespace Tree {
class Node {
protected:
std::string nodename;
NodeType type; //changed to protected
Node(Node::NodeType _type) : type(_type) {}
Node() : Node(UNDEFINED) {} //default constructor
};
}
namespace Tree {
class Element :
public Parent,
public Child,
public virtual Node {
protected:
Element() { //change the init constructor list
type = Node::ELEMENT; //change type inside constructor
}
};
}

Node不应该通过Element初始化吗?,为什么编译器要求我在那里显式初始化?

不。

仅当您创建Element的实例而不是Element的子类时,才会发生这种情况。这与virtual继承有关。

virtual

继承的类必须在派生最多的类的构造函数中正确初始化。 因此,您必须使用:

SpecificElement(const std::string name) : Tree::Node(Node::ELEMENT) {
nodename = name;
}

有了这个,当你构造一个SpecificElement的实例时,Tree::Node子对象只初始化一次,从SpecificElement的构造中初始化一次。Element构造函数中的Tree::Node(Node::Element)部分在运行时被忽略。

这种行为的理由可以在第 12.6.2 节初始化基和成员/10.1 中的标准中找到

最新更新