C++ / 钻石继承 / 静态变量

发布于 2024-10-20 23:04:16 字数 365 浏览 1 评论 0原文

我面临一些设计问题,我想写:

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,因此 i 可能会有一些不明确的内容。我的最终目标是在每个类 B、C 和 D 中都有一个具有相同名称但不同值的静态变量。这可能吗?

预先非常感谢 塞德

I am facing some design problems, I would like to write:

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_; ... };

I think up to the definition of class C, i won't have any problems.. but what will happen when i define class D? Since D will inherit from both B and C, i will probably have something ambiguous. My ultimate goal would be to have in each classes B, C and D a static variable which would have the same name, but a different value. Is that possible?

Many thanks in advance
Sed

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

箹锭⒈辈孓 2024-10-27 23:04:16

你这里的代码非常好。类可以用任何它们想要的名称来定义成员,即使它们与父类中的成员名称相匹配。您遇到麻烦的唯一一次是使用这些名称之一会导致歧义。

在您的情况下,类 BCD 中拥有三个 static 数据成员不会导致任何问题问题和每个类的 type_ 实例将与所有其他类不同。仅仅因为它们具有相同的名称并不意味着 C++ 将它们视为覆盖。只有虚拟成员函数可以被重写。

在每个类及其成员函数的上下文中,对 name_ 的任何引用都将始终引用该类中的 name_,因为类隐藏了其任何基类的名称,并且所以编译器只会查找当前类。在全局范围内,您可以使用完全限定名称引用 name_ 字段,例如 A::name_B::name_ 等。

更重要的是,您在这里使用的继承类型(无论是虚拟的还是非虚拟的)并不重要,因为这里的问题只是变量的命名。由于每个 static 数据成员只有一个副本,因此您的类 D 最终是否继承 A::name_ 的两个副本并不重要任何担忧;它不能继承两个副本,因为只存在一个。

The code you have here is perfectly fine. Classes are allowed to define members with whatever names they want, even if they match the name of a member in a parent class. The only time you'll run into trouble is if using one of those names would lead to an ambiguity.

In your case, having three static data members in the classes B, C, and D will not cause any problems and each class's instance of type_ will be distinct from all the others. Just because they have the same name doesn't mean that C++ treats them as overrides; only virtual member functions can be overridden.

Within the context of each class and its member functions, any references to name_ will always refer to the name_ from that class, since classes hide names from any of their base classes and so the compiler will only look in the current class. Globally, you can refer to the name_ fields with their fully-qualified names, like A::name_, B::name_, etc.

More importantly, the type of inheritance you use here, whether virtual or non-virtual, does not matter because all that's at issue here is the naming of the variables. Since there's only one copy of each static data member, whether your class D ends up inheriting two copies of A::name_ isn't of any concern; it can't inherit two copies since only one exists.

征﹌骨岁月お 2024-10-27 23:04:16

那里没有任何含糊之处。您可以将这两个字段称为 B::type_C::type_

There is nothing ambiguous at all there. You will be able to refer to both fields as B::type_ and C::type_.

衣神在巴黎 2024-10-27 23:04:16

如果您在 D 的方法中写入 type_,它将解析为 Dtype_。如果您编写 A::name_B::name_,它将解析为相应实例的 type_

另一方面,似乎您可能试图将某种反射系统破解到 C++ 上,因为每个类中都有名为 type_ 的静态字段。在某些罕见的情况下,这可能很有用,但这可能是一个坏主意。

If you write type_ in a method in D, it will resolve to D's type_. If you write A::name_ or B::name_, it will resolve to the respective instance's type_.

On a different note, it seems as if you might be trying to hack some kind of reflection system onto C++, since you have static fields called type_ in each class. That might be useful under some rare circumstances, but it's probably a bad idea.

夏尔 2024-10-27 23:04:16

在菱形继承中,C++ 标准提供了一种解决方案来避免出现歧义。

您的类定义结构看起来像

                       A
                      /  \
                     /    \
                    /      \
                   B        C
                    \      /
                     \    /
                      \  /
                       D 

现在,当您在类 B 中继承类 A 时,

class B : public virtual A

对类 C 使用以下相同的内容

。那么 C 就只有一个 A 类的实例。

不需要为 D 类进行虚拟继承。它没有任何效果。

类D的大小可以与之前相同,但是来自类B和类的变量访问的任何地址。当您创建 D 的实例时,C 类将是相同的。

In diamond inheritance there is one solution provided by C++ standard to avoid something ambiguous.

Your structure of class definition looks likes like

                       A
                      /  \
                     /    \
                    /      \
                   B        C
                    \      /
                     \    /
                      \  /
                       D 

Now when you inherit class A in class B use following

class B : public virtual A

Same things for class C.

So when any class inherit from class B & C then it will have just one instance of class A.

No need to virtual inherit for class D. It has no effect.

Size of class D may be same as before but any address of variable access from class B & class C will be same when you create instance of D.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文