C++ C++;/菱形继承/静态变量
我面临一些设计问题,我想写:C++ C++;/菱形继承/静态变量,c++,inheritance,static,diamond-problem,C++,Inheritance,Static,Diamond Problem,我面临一些设计问题,我想写: class A { ... }; class B : public A { static string type_; ... }; class C : public A { static string type_; ... }; class D : public B, public C { static string type_; ... }; 我认为按照C类的定义,我不会有任何问题。。但是当我定义D类时会发生什么呢?由于D将同时从B和C继承,我可能会有一些模棱两
class A { ... };
class B : public A { static string type_; ... };
class C : public A { static string type_; ... };
class D : public B, public C { static string type_; ... };
我认为按照C类的定义,我不会有任何问题。。但是当我定义D类时会发生什么呢?由于D将同时从B和C继承,我可能会有一些模棱两可的东西。我的最终目标是在每个类B、C和D中都有一个静态变量,该变量的名称相同,但值不同。可能吗
非常感谢
Sed这里的代码非常好。类可以用它们想要的任何名称定义成员,即使它们与父类中成员的名称匹配。你唯一会遇到麻烦的时候就是如果使用其中一个名字会导致歧义 在您的情况下,在类
B
、C
和D
中有三个静态
数据成员不会导致任何问题,并且每个类的类型的实例将不同于所有其他类。仅仅因为它们有相同的名称并不意味着C++将它们视为重写;只能重写虚拟
成员函数
在每个类及其成员函数的上下文中,对name
的任何引用都将始终引用该类中的name
,因为类对其任何基类都隐藏名称,因此编译器将只查看当前类。在全局范围内,您可以使用其完全限定名引用name
字段,如A::name
、B::name
等
更重要的是,您在这里使用的继承类型,无论是虚拟的还是非虚拟的,都无关紧要,因为这里讨论的是变量的命名。由于每个静态
数据成员只有一个副本,因此您的类D
是否最终继承了A::name
的两个副本并不重要;它不能继承两个副本,因为只有一个副本存在。没有任何不明确的地方。您可以将这两个字段都称为“代码> b::Type 和C::Type .< /P> < P>在菱形继承中,有一种由C++标准提供的解决方案,以避免某些含糊之处。
您的类定义结构如下所示
A
/ \
/ \
/ \
B C
\ /
\ /
\ /
D
现在,当您在类B中继承类A时,请使用以下命令
class B : public virtual A
C类也一样
因此,当任何类从类B&C继承时,它将只有一个类A的实例
类D不需要虚拟继承。它没有效果
类D的大小可能与以前相同,但当您创建D的实例时,来自类B和类C的变量访问的任何地址都将相同。如果您在D
中的方法中写入type
,它将解析为D
。如果您编写A::name
或B::name
,它将解析为相应实例的类型
在不同的注释中,似乎你可能试图把某种反射系统强加给C++,因为在每个类中都有静态字段称为“代码> Type”/CODE。在某些罕见的情况下,这可能是有用的,但这可能是个坏主意。@thkala:尝试一些东西可能有用,但它只能告诉您当前实现中发生了什么。它不能告诉你应该发生什么或者结果是否未定义。-1这是对虚拟继承的一个很好的描述,但我不认为它回答了这里提出的问题。无论如何,谢谢,我知道虚拟继承模式,但这确实不是我的问题。SED感谢templatetypedef花时间解释底层机制,我有点不知所措,并且确信它不起作用。type\uu
变量都是static
,因此不同对象的单个实例不会有任何字段副本。它们只是各自类内部的全局变量,不参与类布局。我没有看到它们是静态的。我现在已经改变了答案。