I have a class that contains a lot a data. Depending on the situation I need to output this data in different ways. I want the output routines for each of those situations separated and I want to keep the base class clean of that.
Is it absolutely safe to cast to a derived class that does NOT add any data members but just non-virtual functions?
#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;
}
The part where class "Derived3" (that has virtual inheritance of "Base") is cast to "Base" first and then to "Derived1"/"Derived2" does not look very good to me but I know how c-style casts are frowned upon in the c community. In this small example however, the c-style cast are compiling and working nicely:
I know there is the issue with multiple inheritance where a cast to one of the base classes can have a different pointer address then the inherited class it was cast from. So I understand that it might be too dangerous to rely on it.
Are the static casts I did in the example at the top safe?
CodePudding user response:
No, this isn't safe. The behaviour of the program is undefined.
Static casting to a derived type is safe only when the dynamic type of the object is that derived type (or a further derived type).