On 3 mar, 12:48, DeMarcus <use_my_alias_h...@hotmail.com> wrote:
Hi.
I need to store pointers as void* to be able to check that an
(semi-arbitrary) object cannot be used twice.
It looks like this.
template<typename T>
class BaseClass
{
T t;
};
std::set<const void*> checklist;
template<typename T>
bool testAndSet( const BaseClass<T>& object )
{
// Insert object into set, if already inserted, return false.
return checklist.insert( &object ).second;
}
int main()
{
BaseClass<int> intClass;
assert( testAndSet( intClass ) && "Should not fail" );
assert( testAndSet( intClass ) && "Should fail" );
}
Regarding the conversion to const void* when inserting into the set,
this must be safe, right?
Yes. It is safe.
Since everything that comes into testAndSet()
are implicitly cast to BaseClass<T> the void* must always be the same
for any single object.
It will be the same for any single address. This is equivalent to a
reinterpret_cast<void*>().
If you want it to be the same for any single object, you must use a
dynamic_cast<void*>(). You will the have a pointer on the most derived
underlying object.
In a previous post Alf P. Steinbach showed the following problem.
struct A
{
int a;
};
struct B : A
{
virtual ~B() {}
int b;
};
int main()
{
B* p1 = new B;
A* p2 = p1;
void* pv1 = p1;
void* pv2 = p2;
assert( pv1 == pv2 && "Fails!" );
}
But isn't my example safe from that since I do an implicit cast in the
function argument, similar to doing the following.
int main()
{
B* p1 = new B;
A* p2 = p1;
void* pv1 = static_cast<A*>(p1);
void* pv2 = static_cast<A*>(p2);
assert( pv1 == pv2 && "Should be ok" );
}
Am I correct about this assumption? Does it say in the standard that two
different pointers to the same object will always be identical after an
implicit cast through a function call like my testAndSet example above?
If you are guaranteed that you have only one ancestor, yes but see the
problem:
struct A
{
int a;
};
struct B : A
{
virtual ~B() {}
int b;
};
struct C : A
{
virtual ~C() {}
int c;
};
struct D : B, C
{
virtual ~D() {}
int d;
};
main()
{
C* p1 = new C;
A* p2 = p1;
B* p3 = p1;
void* pv1 = static_cast<A*>(p2);
void* pv2 = static_cast<A*>(p3);
assert( pv1 == pv2 && "Should Fail" );
}
--
Michael
B* p3 = p1; will give a compiler error, which is fine.
I guess you meant the following.