Error / Incorrect C2248 Error Using Visual Studio 2010

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:
   // private, unimplemented copy constructor and assignment operator
   // to guarantee that ObjectPtr<T> objects are not copied
   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;
};

// Some concrete type that holds useful data
class SomeUsefulData {
public:
   SomeUsefulData () {}
   ~SomeUsefulData () {}
};

// Some concrete type that holds a heap-allocated instance of
// SomeUsefulData
class SomeContainer {
public:
   SomeContainer (SomeUsefulData* pUsefulData)
   {
      m_pData = pUsefulData;
   }
   ~SomeContainer ()
   {
      // nothing to do here
   }
public:
   bool EvaluateSomeCondition ()
   {
      // fake condition check to give us an expression
      // to use in ?: operator below
      return true;
   }
   SomeUsefulData* Foo ()
   {
      // this usage of the ?: operator generates a C2248
      // error b/c it attempting to call the copy
      // constructor on ObjectPtr<T>
      return EvaluateSomeCondition() ? m_pData : NULL;
      /**********[ DISCUSSION ]**********
      The following equivalent constructs compile
      w/out error and behave correctly:

      (1) explicit cast to SomeUsefulData* as a comiler hint
      return EvaluateSomeCondition() ? (SomeUsefulData *)m_pData : NULL;

      (2) if/else instead of ?:
      if (EvaluateSomeCondition())
         return m_pData;
      else
         return NULL;

      (3) skip the condition check and return m_pData as a
          SomeUsefulData* directly
      return m_pData;
      **********[ END DISCUSSION ]**********/
   }
private:
   ObjectPtr<SomeUsefulData> m_pData;
};

int _tmain(int argc, _TCHAR* argv[])
{
   return 0;
}
+3
2

++, , . 102-103, -, expression ? E1 : E2, T1 T2, T1 T2 , - r-,

, , . , , . , . .

, ( ObjectPtr, operator T*), , , .

+1

:

   ObjectPtr(T* pObj = NULL, bool bShared = false) :
      m_pObject(pObj), m_bObjectShared(bShared)
   {}

( <T>)

, . . ...

+2

Source: https://habr.com/ru/post/1746023/


All Articles