Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it ok to static_cast a void* pointer

Tags:

c++

casting

For example, propose map<int,void*>hold where void* is always storing pointers from classA is it safe to cast it back later via static_cast?

classA* ptr = static_cast<classA*>( holditerator->second );

the reason void* is used is because hold is member of a class defined on a header used by some cpp files which don't know what classA is. I would have to include the header of classA definitions on these cpp files which can't be done by many reasons.

like image 438
snoopy Avatar asked Aug 25 '12 09:08

snoopy


2 Answers

Yes, static_cast is OK in that case and the right thing to use.

I have to ask why you don't store classA* pointers in the first place though. If you want to put derived class pointers into it, then beware, you need to upcast/upconvert (implicitly or explicitly) the derived class pointers to classA* before you put them into the map.

But even if you put also derived class pointers into the map, a base class pointer would suffice because a derived class pointer is implicitly convertible to a base class pointer.

The reason void* is used is because hold is member of a class define on a header used by some cpp files which don't know what classA is.

That can be a valid reason to prevent layering violations.

I would have to include the header of classA definitions on these cpp files which can't be done by many reasons.

That's most probably not necessary in your case. A forward declaration suffices. If the header knows what is put into the map, but just wants to avoid including additional headers, this is the way to go.

like image 101
Johannes Schaub - litb Avatar answered Oct 27 '22 00:10

Johannes Schaub - litb


As Johannes explained, the static_cast is ok. Another technique to prevent the dependencies to ClassA in the cpp files is to use the pimpl idiom.

// in header file
class classB {
public:
    classB();
    ~classB();
private:
    class impl;
    unique_ptr<impl> pimpl;
};



// in implementation file
#include "classA.hpp"

class classB::impl 
{
    std::map<int, classA> hold;  // hidden in implementation file
};

classB::classB() : pimpl{ new impl{ /*...*/ } } { }
classB::~classB() { } 
like image 23
hansmaad Avatar answered Oct 26 '22 23:10

hansmaad