☰
  • 首页
  • 规则分类
  • 项目介绍
search
•••

避免多重继承自同一非虚基类

5.1.5 ID_diamondInheritance
目录 › next › previous

当派生类有多个基类,这些基类又派生自同一非虚基类时,派生类对象会持有该非虚基类的多个实例,造成逻辑和存储上的冗余。

示例:

struct A {
    int i = 0;
};

class B: public A {};
class C: public A {};
class D: public B, public C {};   // Non-compliant

void foo(D& d) {
    d.i = 1;       // Compile error
    d.B::i = 1;    // Odd
    d.C::i = 1;    // Odd
}

在 D 类对象 d 中,基类 A 的成员 i 有两个不同的实例,d 不能直接访问 i,只能通过 d.B::i 或 d.C::i 这种怪异的方式访问。

将共同的基类设为虚基类可以解决这种问题:

class B: virtual public A {};
class C: virtual public A {};
class D: public B, public C {};   // Compliant

void foo(D& d) {
    d.i = 1;       // OK
}

注意,直接将虚基类指针转为派生类指针会导致标准未定义的行为,如:

void bar(A* a) {
    B* p = (B*)a;  // Undefined behavior
    ....
}

这种转换一般不会通过编译,但标准并未要求编译器必须阻止这种转换,改用 dynamic_cast 可解决这些问题:

void bar(A* a) {
    B* p = dynamic_cast<B*>(a);  // OK
    ....
}

相关

ID_diamondExceptionInheritance

依据

ISO/IEC 14882:2003 5.2.9(5 8)-undefined ISO/IEC 14882:2003 10.1(4 5 6) ISO/IEC 14882:2011 5.2.9(11 12)-undefined ISO/IEC 14882:2011 10.1(4 5 6 7)

参考

C++ Core Guidelines C.137
Copyright©2024 360 Security Technology Inc., Licensed under the Apache-2.0 license.