I have an object of class A that I want to allocate on a custom stack object. To do this, I simply move the stack pointer as many bytes as the object is in size and return its previous value:
class A : public B {}; //B is from a precompiled library
class stack {
public:
stack(void): _top(&_storage[0]) {}
template <typename T>
inline T* push(void) {
T* ptr = static_cast<T*>(_top);
_top += sizeof(T);
return ptr;
}
//...
private:
char _storage[1024];
char* _top;
};
stack _stack;
int main(int argc, char** argv) {
A* a = _stack.push<A>(); //ignore the lack of a constructor call
return 0;
}
Visual C++ simply tells me that static_cast cannot convert from char* to A*. A regular C style cast does not give me this error, but I'd rather be more explicit and avoid a dynamic cast (A inherits from another class, but does not contribute to the vtable it doesn't have). Is there any difference between the two in this case?
Static Cast: This is the simplest type of cast which can be used. It is a compile time cast.It does things like implicit conversions between types (such as int to float, or pointer to void*), and it can also call explicit conversion functions (or implicit ones).
You shouldn't use static_cast for casting down an inheritance hierarchy, but rather dynamic_cast . That will return either the null pointer or a valid pointer.
As we learnt in the generic types example, static_cast<> will fail if you try to cast an object to another unrelated class, while reinterpret_cast<> will always succeed by "cheating" the compiler to believe that the object is really that unrelated class.
In short: static_cast<>() gives you a compile time checking ability, C-Style cast doesn't. static_cast<>() is more readable and can be spotted easily anywhere inside a C++ source code, C_Style cast is'nt. Intentions are conveyed much better using C++ casts.
As others have said, the solution is to use reinterpret_cast
, which is meant to be used when casting between unrelated pointer types:
T* ptr = reinterpret_cast<T*>(_top);
If you use placement new
instead, you not only avoid the casting problem but you also fix the problem of not calling the constructor for types that have a constructor:
T* ptr = new(_top) T();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With