【问题标题】:Chained inheritance of empty classes, still necessary?空类的链式继承,还有必要吗?
【发布时间】:2019-06-12 06:25:01
【问题描述】:

是否还有充分的理由使用链式基本案例而不是平面多重继承?

过去,有些类被设计成链式继承。我认为这是强制空基类优化。 我知道这就是 Boost.Operators 的设计方式。

struct empty{};

template<class Base = empty>
struct A : Base{}; 

template<class Base = empty>
struct B : Base{}; 

template<class Base = empty>
struct C : Base{};

struct S : A<B<C<>>>{};

int main(){static_assert(sizeof(S)==1, "!");}

这在新编译器中是否有必要(今天是 2019 年),或者我可以放弃所有复杂性并接受正常的继承?

struct A{}; 

struct B{}; 

struct C{};

struct S : A, B, C{};

int main(){static_assert( sizeof(S) == 1 , "!");}

它是否有任何主要或次要目的?

【问题讨论】:

  • 你应该引入一些虚函数。然后它可能会与更多的编译器相关。
  • @Justin,好的,那么对于没有非常大的类来说,VisualStudio 仍然需要它(并且他们想出了自己的解决方法。)
  • EBO 是可选的,因此在这两种情况下,assert 都可能触发。
  • @Jarod42,编译器可以选择 EBO 来实现吗?我猜这种疯狂会在 C++ 重新发现 0 时结束。(当sizeof(S) == 0open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0146r1.html

标签: c++ c++11 multiple-inheritance base-class empty-class


【解决方案1】:

[class.derived]/7 中的标准规定:

基类子对象可能大小为零。

这意味着 EBO 不是编译器必须实现的。然而几乎所有的编译器都实现了它。

从 C++20 开始,[[no_unique_address]] 属性可以应用于空成员子对象:

如果空成员子对象使用属性[[no_unique_address]],则可以像空基一样优化它们。获取此类成员的地址会产生一个地址,该地址可能等于同一对象的其他成员的地址。

【讨论】:

  • 谢谢,我想知道属性在继承的上下文中是如何使用的,示例是针对成员变量的:en.cppreference.com/w/cpp/language/attributes/no_unique_address
  • 不确定我明白你的意思。由于 EBO,继承类的子对象在派生类中的大小无论如何都会为 0。你能举个例子说明你想要达到的目标吗?
  • 不,很抱歉造成混淆,我只是想知道该属性在我的示例中的位置。
猜你喜欢
  • 1970-01-01
  • 2011-08-29
  • 2014-01-25
  • 2016-03-05
  • 1970-01-01
  • 1970-01-01
  • 2011-07-17
  • 1970-01-01
  • 2011-12-24
相关资源
最近更新 更多