Re: Is void* as key a bad idea?
James Kanze wrote:
On Feb 18, 7:11 pm, "Leigh Johnston" <le...@i42.co.uk> wrote:
One, you know the type of pointers in the set. Or at least a
common interface type. Then declare the set with that type
(not done above).
There is nothing fundamentally wrong with using void* in a
container however for the particular case of ensuring variable
identity there are corner cases yes, the main one being two
"variables" occupying the same address (class object and its
first member variable).
The other potential problem is that two pointers to the same
object might not compare equal, if they're obtained from
different base classes.
I don't know exactly what the original poster is trying to
accomplish, so it's difficult to be more precise. If he can
use a common base class, and a pointer to that, that's generally
a better solution than using void*. If he can't, and is
interested in registering complete objects, he has to somehow
ensure that it is always a pointer to the most derived class
that gets converted into void*.
I have a kind of factory that creates objects of any type. It is built
on a template function and it uses variables to initialize the objects.
However, one init variable can only be used once, that is what I'm
trying to prevent. It is similar to this.
class Factory
{
public:
template<typename T>
T* createObject( T* init )
{
if( regSet_.insert( init ).second == false )
throw Error();
return new T( init );
}
private:
std::set<void*> regSet_;
};
I can't make Factory a template since I need to store more common data.
Is this a hopeless situation?
Or two, the set will contain pointers to objects of
different types. Generally this is only meaningful for
class types. Then void* might be suitable but you need to be
sure to store pointers to most derived objects (not done
above).
You can use dynamic_cast<void*>(p) to obtain most derived
object pointers if every type is polymorphic. Otherwise you
risk not detecting that a pointer to an object is already in
the set. Pointers to the same object but accessed via
different static types may /not/ necessarily yield the same
void* pointers.
Only use dynamic_cast sparingly and in this case it is only
really required if multiple inheritance is being used.
Or not---formally, it depends on the implementation.
Practically, of course, regardless of the implementation, some
day, someone will use multiple inheritance, and you're screwed.
This doesn't look good. I mean policies by Alexandrescu are built on
multiple inheritance.
--
James Kanze