On 4/10/2014 2:43 PM, (e-mail address removed) wrote:
If you want us to analyze the code and offer work-arounds, we need to
see the code. Don't post it as it is. Distill it. Rename the classes,
the templates, the types, the members. Remove irrelevant parts. Make
sure that the distilled code still gives you the same error message when
compiled with the same compiler. Then post.
SNIP
Here we go. You can replace boost::shared_ptr with std::shared_ptr in C++'11:
// Boost Includes
#include <boost/shared_ptr.hpp>
//------------------------------------------------
class IRetainable
{
public:
virtual ~IRetainable() {};
protected:
virtual void Relinquish() = 0;
virtual void Retain() = 0;
};
//------------------------------------------------
class MyTestClass;
//------------------------------------------------
template<class T>
class RetainedV2
{
public:
// TODO - This is my question:
/// I am not sure why we must friend possible T types of this class
// What are they calling? I know we are calling their Retain and Relinquish,
// but not the other way around.
/// If we do not, the compiler gives a nonsensical error message:
// 'RetainedV2<MyTestClass>::Retain' : cannot access protected member declared in class 'RetainedV2<MyTestClass>'
// The class cannot access its own protected members? huh?
//friend MyTestClass;
RetainedV2(const boost::shared_ptr<T> & resource);
RetainedV2(const RetainedV2<T> & rhs);
~RetainedV2();
RetainedV2<T> & operator = (const boost::shared_ptr<T> & rhs);
boost::shared_ptr<T> operator -> () const;
protected:
void Retain();
void Relinquish();
private:
bool m_isRetained;
boost::shared_ptr<T> m_resource;
};
//------------------------------------------------
template<class T>
RetainedV2<T>::RetainedV2(const boost::shared_ptr<T> & resource)
:
m_resource(resource),
m_isRetained(false)
{
Retain();
}
//------------------------------------------------
template<class T>
RetainedV2<T>::RetainedV2(const RetainedV2<T> & rhs)
:
m_resource(rhs.m_resource),
m_isRetained(false)
{
Retain();
}
//------------------------------------------------
template<class T>
RetainedV2<T>::~RetainedV2()
{
Relinquish();
}
//------------------------------------------------
template<class T>
RetainedV2<T> & RetainedV2<T>:
perator = (const boost::shared_ptr<T> & rhs)
{
Relinquish();
m_resource = rhs;
Retain();
return *this;
}
//------------------------------------------------
template<class T>
void RetainedV2<T>::Retain()
{
if (m_resource && !m_isRetained)
{
m_resource->Retain();
m_isRetained = true;
}
}
//------------------------------------------------
template<class T>
void RetainedV2<T>::Relinquish()
{
if (m_resource && m_isRetained)
{
m_resource->Relinquish();
m_isRetained = false;
}
}
//------------------------------------------------
template<class T>
boost::shared_ptr<T> RetainedV2<T>:
perator -> () const
{
return m_resource;
}
//------------------------------------------------
//------------------------------------------------
class MyTestClass : private IRetainable
{
public:
typedef boost::shared_ptr<MyTestClass> SharedPtr;
// I understand why these friend declarations are needed.
// Because these methods cal protected methods in this class.
// and I need them to be protected, because I don't want anyone else
// to be able to call them.
friend void RetainedV2<MyTestClass>::Retain();
friend void RetainedV2<MyTestClass>::Relinquish();
MyTestClass()
{
}
~MyTestClass()
{
}
protected:
void Retain()
{
}
void Relinquish()
{
}
};
//------------------------------------------------
int main()
{
boost::shared_ptr<MyTestClass> myTestClass(new MyTestClass());
RetainedV2<MyTestClass> retained(myTestClass);
return 0;
}