Code: Select all
ClassA myA;
((ClassB*)(&myA))(...);
can i convert ClassA to ClassB (ClassB : public ClassA)? without using new, and RTTI (typecast)
Code: Select all
ClassA myA;
((ClassB*)(&myA))(...);
can i convert ClassA to ClassB (ClassB : public ClassA)? without using new, and RTTI (typecast)
Code: Select all
classA myA;
classB* myB = static_cast<classB*>(myA);
Thanks neon, one last question can i do this?neon wrote:Hello,
Typecast does not use RTTI. Is it possible? Of course. Without a typecast? No. Also, in C++ static_cast<> should be used here over a C style cast.Code: Select all
classA myA; classB* myB = static_cast<classB*>(myA);
Code: Select all
ClassA MyClass
#ifdef ...
ClassB* MyClassChild = (static_cast<ClassB*>(MyClass))(...); // Call Constructor
MyClass = MyClassChild;
#endif
MyClass.virtualFunction();
i can't use new!. Because i want to do that with local variable without dynamic allocation.berkus wrote:One obvious way of doing it is to use placement new.
Just be aware if there are storage space changes between ClassA and ClassB (and there certainly might be some, unless you explicitly document, require and assert sizeof(a) == sizeof(b)), then you're screwed.Code: Select all
ClassA* a = new ClassA; ClassB* b = new(a) ClassB;
Code: Select all
ClassA BaseClass; // ClassA only contains virtual functions
#ifdef _USE_CLASS_B
// Want to change ClassA to ClassB (ClassB : public ClassA)
#elif _USE_CLASS_C
// Want to change ClassA to ClassC (ClassC : public ClassA)
#endif
BaseClass.VirtualFunction(); // Call the function (BaseClass now is ClassB or ClassC, Can't be ClassA becuase all functions are virtual)
Code: Select all
user@localhost:/void/cygwin/osdev/zbz$ cat ~/tst.cpp
#include <stdlib.h>
#include <stdio.h>
class animal {
public:
virtual void foo(void) { printf("animal::foo()"); };
void bar(void) { printf("animal::bar()"); };
};
class bear
: public animal {
public:
void foo(void) { printf("bear::foo()"); };
void bar(void) { printf("bear::bar()"); };
};
/* The purpose of polymorphism (as done in C++) is to allow you to use a
* pointer or reference to a base class and assign it to an instance of a
* derived class, and even though the _type_ of the pointer being used may be
* of the base class, if the object being pointed to is a derived class with an
* implementation of one of the base class's virtual functions, the _derived_
* class object's implementation of that function will be called, in spite of
* type of the pointer being used to refer to the object. Consider:
**/
animal *pAnim;
bear bearArr[16];
int main(void)
{
for (int i=0; i<16; i++)
{
pAnim = static_cast<animal *>( &bearArr[i] );
pAnim->foo();
};
return EXIT_SUCCESS;
}
user@localhost:/void/cygwin/osdev/zbz$
user@localhost:/void/cygwin/osdev/zbz$ g++ ~/tst.cpp -o ~/tst
user@localhost:/void/cygwin/osdev/zbz$ ~/tst
bear::foo()bear::foo()bear::foo()bear::foo()bear::foo()bear::foo()bear::foo()bear::foo()bear::foo()bear::foo()bear::foo()bear::foo()bear::foo()bear::foo()bear::foo()bear::foo()user@localhost:/void/cygwin/osdev/zbz$
Code: Select all
ClassA BaseClass; // ClassA only contains virtual functions
#ifdef _USE_CLASS_B
// Want to change ClassA to ClassB (ClassB : public ClassA)
#elif _USE_CLASS_C
// Want to change ClassA to ClassC (ClassC : public ClassA)
#endif
BaseClass.VirtualFunction(); // Call the function (BaseClass now is ClassB or ClassC, Can't be ClassA becuase all functions are virtual)
No, you can't do it (properly) without RTTI. You can just reinterpret_cast<> and go your way, but whatever result that yields depends on how similar the base and derived classes are in size and layout, and whatever eccentricities your compiler may have in its handling of inheritance. Also, a common mistake people make is to assume that online "tutorials" on C/C++ are as good as a well known, well reputed book (like K&R or Stroustrup): they are notcan i convert ClassA to ClassB (ClassB : public ClassA)? without using new, and RTTI (typecast)
Obviously. However, every language has a "feel" to it, that one would do well to be cultured in.berkus wrote:Idiomacy of C++ is fairly orthogonal to the idiomacy of patterns used.
Hi,Wolftein wrote:i can't use new!. Because i want to do that with local variable without dynamic allocation.berkus wrote:One obvious way of doing it is to use placement new.
Just be aware if there are storage space changes between ClassA and ClassB (and there certainly might be some, unless you explicitly document, require and assert sizeof(a) == sizeof(b)), then you're screwed.Code: Select all
ClassA* a = new ClassA; ClassB* b = new(a) ClassB;
This is what i'm trying to do.Code: Select all
ClassA BaseClass; // ClassA only contains virtual functions #ifdef _USE_CLASS_B // Want to change ClassA to ClassB (ClassB : public ClassA) #elif _USE_CLASS_C // Want to change ClassA to ClassC (ClassC : public ClassA) #endif BaseClass.VirtualFunction(); // Call the function (BaseClass now is ClassB or ClassC, Can't be ClassA becuase all functions are virtual)
Code: Select all
#ifdef _USE_CLASS_B
ClassB BaseClass();
#else
ClassC BaseClass();
#endif
BaseClass.VirtualFunction();
Code: Select all
ClassA *BaseClass = 0;
ClassB b;
ClassC c;
if(use_class_b) {
BaseClass = &b;
} else {
BaseClass = &c;
}
Code: Select all
class ClassB {};
class ClassC {};
#ifdef SOMETHING
typedef ClassB ClassA;
#else
typedef ClassC ClassA;
#endif
ClassA object;
object.function();