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
,因此不同对象的单个实例不会有任何字段副本。它们只是各自类内部的全局变量,不参与类布局。我没有看到它们是静态的。我现在已经改变了答案。