I see that I consider the compiler error / error using the Visual Studio 2010 compiler. I am updating our code base from Visual Studio 2005, and I came across a construct that was correctly built before, but now generates a C2248 compiler error.
Obviously, the code snippet below has been generalized, but it is a compiled script example. The ObjectPtr<T>C ++ template comes from our code base and is the source of the error. What seems to be happening is that the compiler generates a call to the copy constructor for ObjectPtr<T>when it should not (see My comment block in the method SomeContainer::Foo()below). There is a public distribution operator for SomeUsefulData *on for this code construct ObjectPtr<SomeUsefulData>, but it is not selected inside the expression true if the operator ?:. Instead, I get two errors in the block quote below.
Based on my knowledge of C ++, this code should compile. Has anyone else seen this behavior? If not, can someone point me to an explanation of the compiler permission rules that would explain why it is trying to create a copy of the object in this case?
Thanks in advance,
Dylan Bourke
Visual Studio build result:
c: \ projects \ objectptrtest \ objectptrtest.cpp (177): error C2248: 'ObjectPtr :: ObjectPtr': cannot access the private member declared in the class 'ObjectPtr'
with
[T = SomeUsefulData]
c: \ projects \ objectptrtest \ objectptrtest.cpp (25): see the declaration of an ObjectPtr :: ObjectPtr object
with
[T = SomeUsefulData]
c: \ projects \ objectptrtest \ objectptrtest.cpp (177): error C2248: 'ObjectPtr :: ObjectPtr': cannot access to the private member declared in the ObjectPtr class
with
[T = SomeUsefulData]
c: \ projects \ objectptrtest \ objectptrtest.cpp (25): see the declaration of the ObjectPtr :: ObjectPtr object
with
[T = SomeUsefulData]
, :
#include <stdio.h>
#include <tchar.h>
template<class T>
class ObjectPtr {
public:
ObjectPtr<T> (T* pObj = NULL, bool bShared = false) :
m_pObject(pObj), m_bObjectShared(bShared)
{}
~ObjectPtr<T> ()
{
Detach();
}
private:
ObjectPtr<T> (const ObjectPtr<T>&);
ObjectPtr<T>& operator = (const ObjectPtr<T>&);
public:
T * GetObject ()
{ return m_pObject; }
const T * GetObject () const
{ return m_pObject; }
bool HasObject () const
{ return (GetObject()!=NULL); }
bool IsObjectShared () const
{ return m_bObjectShared; }
void ObjectShared (bool bShared)
{ m_bObjectShared = bShared; }
bool IsNull () const
{ return !HasObject(); }
void Attach (T* pObj, bool bShared = false)
{
Detach();
if (pObj != NULL) {
m_pObject = pObj;
m_bObjectShared = bShared;
}
}
void Detach (T** ppObject = NULL)
{
if (ppObject != NULL) {
*ppObject = m_pObject;
m_pObject = NULL;
m_bObjectShared = false;
}
else {
if (HasObject()) {
if (!IsObjectShared())
delete m_pObject;
m_pObject = NULL;
m_bObjectShared = false;
}
}
}
void Detach (bool bDeleteIfNotShared)
{
if (HasObject()) {
if (bDeleteIfNotShared && !IsObjectShared())
delete m_pObject;
m_pObject = NULL;
m_bObjectShared = false;
}
}
bool IsEqualTo (const T * pOther) const
{ return (GetObject() == pOther); }
public:
T * operator -> ()
{ ASSERT(HasObject()); return m_pObject; }
const T * operator -> () const
{ ASSERT(HasObject()); return m_pObject; }
T & operator * ()
{ ASSERT(HasObject()); return *m_pObject; }
const T & operator * () const
{ ASSERT(HasObject()); return (const C &)(*m_pObject); }
operator T * ()
{ return m_pObject; }
operator const T * () const
{ return m_pObject; }
operator bool() const
{ return (m_pObject!=NULL); }
ObjectPtr<T>& operator = (T * pObj)
{ Attach(pObj, false); return *this; }
bool operator == (const T * pOther) const
{ return IsEqualTo(pOther); }
bool operator == (T * pOther) const
{ return IsEqualTo(pOther); }
bool operator != (const T * pOther) const
{ return !IsEqualTo(pOther); }
bool operator != (T * pOther) const
{ return !IsEqualTo(pOther); }
bool operator == (const ObjectPtr<T>& other) const
{ return IsEqualTo(other.GetObject()); }
bool operator != (const ObjectPtr<T>& other) const
{ return !IsEqualTo(other.GetObject()); }
bool operator == (int pv) const
{ return (pv==NULL)? IsNull() : (LPVOID(m_pObject)==LPVOID(pv)); }
bool operator != (int pv) const
{ return !(*this == pv); }
private:
T * m_pObject;
bool m_bObjectShared;
};
class SomeUsefulData {
public:
SomeUsefulData () {}
~SomeUsefulData () {}
};
class SomeContainer {
public:
SomeContainer (SomeUsefulData* pUsefulData)
{
m_pData = pUsefulData;
}
~SomeContainer ()
{
}
public:
bool EvaluateSomeCondition ()
{
return true;
}
SomeUsefulData* Foo ()
{
return EvaluateSomeCondition() ? m_pData : NULL;
}
private:
ObjectPtr<SomeUsefulData> m_pData;
};
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
Dylan Bourque