如何从钻石继承中的不同类别中获取值
Posted
技术标签:
【中文标题】如何从钻石继承中的不同类别中获取值【英文标题】:How to take values from different classes in diamond-inheritance 【发布时间】:2021-12-01 09:36:19 【问题描述】:#include <iostream>
class A
protected:
std::string _name;
int _points;
int _energy;
public:
A(std::string name, int points, int energy) : _name(name), _points(points), _energy(energy)
A(std::string name) : _name(name), _points(10), _energy(10)
;
class B : public virtual A
public:
B(std::string name): A(name, 20, 20)
;
class C : public virtual A
public:
C(std::string name) : A(name, 30, 30)
;
class D : public B, public C
private:
std::string _name_d;
public:
D(std::string name): A(name), B(name), C(name), _name_d(name)
A::_name = "another name";
_points = B::_points;
_energy = C::_energy;
std::cout << "name class D " << _name_d << std::endl;
std::cout << "name class A " << A::_name << std::endl;
std::cout << "energy class D " << _energy << std::endl;
std::cout << "points class D " << _points << std::endl;
;
int main(void)
D d("Bill");
return (0);
这是我的第一个 Diamond 继承代码。在 C 类上,我需要从 B 类中获取 _points 的值,从 C 类中获取 _energy 的值,但接下来是输出:
name class D Bill
name class A another name
energy class D 10
points class D 10
我该如何解决这个问题?
【问题讨论】:
听起来您不想使用虚拟继承,那么,如果您希望D
实例的B
和C
子对象具有不同的底层A
子子对象.
通常应该避免多重继承,甚至更多地使用菱形继承或虚拟继承......它会使代码更难维护。事实上,很多语言不支持多重继承(或者只支持接口)。
【参考方案1】:
首先要注意的是,无论你使用哪个前缀,成员变量都是同一个对象。我的意思是:
A::_name
与 B::_name
和 C::_name
和 D::_name
相同
A::_points
与 B::_points
和 C::_points
和 D::_points
相同
等
第一个被调用的构造函数是来自虚拟基类的构造函数,然后是中间类,最后是派生类。
中间类对基类的构造没有影响。
所以你得到的输出非常好:字段_name_d
仅属于类D
,但其他三个在四个类中可用,因为它们是在基虚拟类中声明的。
如果您打算拥有B::_points = 20
和C::_points = 30
,那么您将不得不创建更多对象,因为D
类型的任何对象都会将它们设置为10
。
再次重申:您只有一个对象,并且只有一个 _name
和 _points
和 _energy
。
【讨论】:
以上是关于如何从钻石继承中的不同类别中获取值的主要内容,如果未能解决你的问题,请参考以下文章