PDA

Visualizza la versione completa : [C++] Uso di "smart pointers" annidati


giuseppe500
21-08-2011, 16:03
ciao.
Sto utilizzando un semplice smart pointer di un progetto opensource in opengl(lo smart pointer è del progetto ).
Ho un semplice problema a cui chiedo soluzione:
Ho uno smart pointer che contiene altri smart pointer, quando questo arriva a riferimenti 0 scatta automaticamente il decremento dei riferimenti degli smart pointer annidati?

Il problema è che non so perchè lo smart pointer arriva quando dovrebbe essere distrutto ad avere un conteggio di riferimenti == 1 anzichè == 0.
e non viene distrutto , di conseguenza tutti gli altri smart pointer annidati non decrementano e mi trovo con un bel po di memory leak.

Che tipo di errori potrei aver commesso per arrivare a questo risultato?


ps.se decremento manualmente lo smart pointer tutto funziona correttamente: gli oggetti vengono distrutti e non ho leak.

grazie.

MItaly
21-08-2011, 17:16
Dovresti specificare che smart pointer usi e che cosa intendi per "smart pointers annidati".

giuseppe500
21-08-2011, 18:09
si , scusa .
questo è lo smart pointer che uso:

header:


// Geometric Tools, LLC
// Copyright (c) 1998-2010
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
// http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
//
// File Version: 4.10.0 (2009/11/18)

#ifndef WM4SMARTPOINTER_H
#define WM4SMARTPOINTER_H

#include "Wm4GraphicsLIB.h"

namespace Wm4
{

template <class T>
class Pointer
{
public:
// construction and destruction
Pointer (T* pkObject = 0);
Pointer (const Pointer& rkPointer);
~Pointer ();

// implicit conversions
operator T* () const;
T& operator* () const;
T* operator-> () const;

// assignment
Pointer& operator= (T* pkObject);
Pointer& operator= (const Pointer& rkReference);

// comparisons
bool operator== (T* pkObject) const;
bool operator!= (T* pkObject) const;
bool operator== (const Pointer& rkReference) const;
bool operator!= (const Pointer& rkReference) const;

protected:
// the shared object
T* m_pkObject;
};

#include "Wm4SmartPointer.inl"

}

#endif


.cpp


// Geometric Tools, LLC
// Copyright (c) 1998-2010
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
// http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
//
// File Version: 4.10.0 (2009/11/18)

//----------------------------------------------------------------------------
template <class T>
Pointer<T>::Pointer (T* pkObject)
{
m_pkObject = pkObject;
if (m_pkObject)
{
m_pkObject->IncrementReferences();
}
}
//----------------------------------------------------------------------------
template <class T>
Pointer<T>::Pointer (const Pointer& rkPointer)
{
m_pkObject = rkPointer.m_pkObject;
if (m_pkObject)
{
m_pkObject->IncrementReferences();
}
}
//----------------------------------------------------------------------------
template <class T>
Pointer<T>::~Pointer ()
{
if (m_pkObject)
{
m_pkObject->DecrementReferences();
}
}
//----------------------------------------------------------------------------
template <class T>
Pointer<T>::operator T* () const
{
return m_pkObject;
}
//----------------------------------------------------------------------------
template <class T>
T& Pointer<T>::operator* () const
{
return *m_pkObject;
}
//----------------------------------------------------------------------------
template <class T>
T* Pointer<T>::operator-> () const
{
return m_pkObject;
}
//----------------------------------------------------------------------------
template <class T>
Pointer<T>& Pointer<T>::operator= (T* pkObject)
{
if (m_pkObject != pkObject)
{
if (pkObject)
{
pkObject->IncrementReferences();
}

if (m_pkObject)
{
m_pkObject->DecrementReferences();
}

m_pkObject = pkObject;
}
return *this;
}
//----------------------------------------------------------------------------
template <class T>
Pointer<T>& Pointer<T>::operator= (const Pointer& rkPointer)
{
if (m_pkObject != rkPointer.m_pkObject)
{
if (rkPointer.m_pkObject)
{
rkPointer.m_pkObject->IncrementReferences();
}

if (m_pkObject)
{
m_pkObject->DecrementReferences();
}

m_pkObject = rkPointer.m_pkObject;
}
return *this;
}
//----------------------------------------------------------------------------
template <class T>
bool Pointer<T>::operator== (T* pkObject) const
{
return m_pkObject == pkObject;
}
//----------------------------------------------------------------------------
template <class T>
bool Pointer<T>::operator!= (T* pkObject) const
{
return m_pkObject != pkObject;
}
//----------------------------------------------------------------------------
template <class T>
bool Pointer<T>::operator== (const Pointer& rkPointer) const
{
return m_pkObject == rkPointer.m_pkObject;
}
//----------------------------------------------------------------------------
template <class T>
bool Pointer<T>::operator!= (const Pointer& rkPointer) const
{
return m_pkObject != rkPointer.m_pkObject;
}
//----------------------------------------------------------------------------



con typedef Pointer<Cnomeclassetiposmartpointer> smartpointerPtr;
creo lo smart pointer di tipo "Cnomeclassetiposmartpointer"

per smart pointers annidati volevo dire che la classe da cui creo lo smart pointer incapsula altri smart pointers come variabili membro:



class Cnomeclassetiposmartpointer
{
SmartPointerA;
SmartPointerB;

};


inoltre ho un dubbio ,se ho degli smartpointers in un container stl e richiamo clear() si decrementa il reference counter?
come fa a scegliere se decrementare / incrementare il reference counter?

grazie.


pardon , l'inc:


// Geometric Tools, LLC
// Copyright (c) 1998-2010
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
// http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
//
// File Version: 4.10.0 (2009/11/18)

//----------------------------------------------------------------------------
template <class T>
Pointer<T>::Pointer (T* pkObject)
{
m_pkObject = pkObject;
if (m_pkObject)
{
m_pkObject->IncrementReferences();
}
}
//----------------------------------------------------------------------------
template <class T>
Pointer<T>::Pointer (const Pointer& rkPointer)
{
m_pkObject = rkPointer.m_pkObject;
if (m_pkObject)
{
m_pkObject->IncrementReferences();
}
}
//----------------------------------------------------------------------------
template <class T>
Pointer<T>::~Pointer ()
{
if (m_pkObject)
{
m_pkObject->DecrementReferences();
}
}
//----------------------------------------------------------------------------
template <class T>
Pointer<T>::operator T* () const
{
return m_pkObject;
}
//----------------------------------------------------------------------------
template <class T>
T& Pointer<T>::operator* () const
{
return *m_pkObject;
}
//----------------------------------------------------------------------------
template <class T>
T* Pointer<T>::operator-> () const
{
return m_pkObject;
}
//----------------------------------------------------------------------------
template <class T>
Pointer<T>& Pointer<T>::operator= (T* pkObject)
{
if (m_pkObject != pkObject)
{
if (pkObject)
{
pkObject->IncrementReferences();
}

if (m_pkObject)
{
m_pkObject->DecrementReferences();
}

m_pkObject = pkObject;
}
return *this;
}
//----------------------------------------------------------------------------
template <class T>
Pointer<T>& Pointer<T>::operator= (const Pointer& rkPointer)
{
if (m_pkObject != rkPointer.m_pkObject)
{
if (rkPointer.m_pkObject)
{
rkPointer.m_pkObject->IncrementReferences();
}

if (m_pkObject)
{
m_pkObject->DecrementReferences();
}

m_pkObject = rkPointer.m_pkObject;
}
return *this;
}
//----------------------------------------------------------------------------
template <class T>
bool Pointer<T>::operator== (T* pkObject) const
{
return m_pkObject == pkObject;
}
//----------------------------------------------------------------------------
template <class T>
bool Pointer<T>::operator!= (T* pkObject) const
{
return m_pkObject != pkObject;
}
//----------------------------------------------------------------------------
template <class T>
bool Pointer<T>::operator== (const Pointer& rkPointer) const
{
return m_pkObject == rkPointer.m_pkObject;
}
//----------------------------------------------------------------------------
template <class T>
bool Pointer<T>::operator!= (const Pointer& rkPointer) const
{
return m_pkObject != rkPointer.m_pkObject;
}
//----------------------------------------------------------------------------

MacApp
21-08-2011, 19:27
Stai per caso usando smartpointer derivati da Wm4::Pointer?
Insomma una roba del genere:


class MyPointer: public Wm4::Pointer <int>{
...
};

giuseppe500
21-08-2011, 19:50
Originariamente inviato da MacApp
Stai per caso usando smartpointer derivati da Wm4::Pointer?
Insomma una roba del genere:


class MyPointer: public Wm4::Pointer <int>{
...
};


no.

Loading