将 class 转换为仅添加附加功能的派生 class 是否安全?

Is it safe to cast a class to a derived class that just adds additional functions?

我有一个包含大量数据的 class。根据情况,我需要以不同的方式输出这些数据。我希望将每种情况的输出例程分开,并且我希望保持基础 class 干净。

转换为不添加任何数据成员而仅添加非虚函数的派生 class 是否绝对安全?

#include <stdio.h>

class Base {
public:
  Base() { printf("Base()\n"); }
  
  double A = 3.14;
  int B = 5;
  int C = 42;
};

class Derived1 : public Base {
public:
  Derived1() { printf("Derived1()\n"); }
  
  void DoStuff() {
    // doing stuff with base class's data
    printf("  A = %.4f\n", A);
    printf("  B = %d\n", B);
    printf("  C = %d\n", C);
  }
};

class Derived2 : public Base {
public:
  Derived2() { printf("Derived2()\n"); }

  void DoStuff() {
    // doing stuff with base class's data in a slightly different way
    printf("  A = %.4f, B = %d, C = %d\n", A, B, C);
  }
};

class OtherBase {
public:
  OtherBase() { printf("OtherBase()\n"); }
  int D = 10;
};

class Derived3 : virtual public OtherBase, virtual public Base {
public:
  Derived3() { printf("Derived3()\n"); }
  
  void SomeFunction() {
    A = 6.28;
    B = 1;
    C = 500;
    printf("Done some other stuff.\n");
  }
};

int main() {
  printf("Base class\n\n");
  Base* Instance = new Base();
  printf("Cast to Derived1:\n");
  static_cast<Derived1*>(Instance)->DoStuff();
  printf("Cast to Derived2:\n");
  static_cast<Derived2*>(Instance)->DoStuff();
  
  printf("\nOther class derived from base class\n\n");
  Derived3* Instance2 = new Derived3();
  Instance2->SomeFunction();
  printf("Cast to Derived1:\n");
  static_cast<Derived1*>(static_cast<Base*>(Instance2))->DoStuff();
  printf("Cast to Derived2:\n");
  static_cast<Derived2*>(static_cast<Base*>(Instance2))->DoStuff();
  printf("c-style cast to Derived1:\n");
  ((Derived1*) Instance2)->DoStuff();
  printf("c-style cast to Derived2:\n");
  ((Derived2*) Instance2)->DoStuff();
  return 0;  
}

class“Derived3”(具有“Base”的虚拟继承)首先转换为“Base”然后转换为“Derived1”/“Derived2”的部分对我来说看起来不太好但我知道 C ++ 社区如何不赞成 C 风格的转换。然而,在这个小例子中,c 风格的转换正在编译并且工作得很好:

我知道多重继承存在问题,其中一个基础 classes 的转换可以具有与从中转换继承的 class 不同的指针地址。所以我明白依赖它可能太危险了。

我在顶部示例中执行的静态转换安全吗?

不,这不安全。程序的行为未定义。

仅当对象的动态类型是该派生类型(或进一步的派生类型)时,静态转换为派生类型才是安全的。