NMTop40
March 25th, 2002, 07:37 AM
The new version is at:
http://www.nmtop40.com/CodeBase/SmartPtrT.h
For one thing I've changed the name of the main class from CSmartPtr to SharedPtr (I don't like the C prefix - and there are different types of smart-pointers. The file has retained its name because it contains other classes too).
One of the significant changes is the second template parameter - which defaults to the first. This, I found, was the solution to my "dependency" problem. The problem is that I had a situation as follows (using the new names):
// file B.h
//
class A;
class B
{
private:
//
std::vector< SharedPtr< A > > m_vectOfA;
public:
// public stuff
};
// file main.cxx
void main()
{
B b;
// do stuff with b
};
The problem was that compiling main.cxx it complained that A was undefined when it tried to call the method Release() in the destructor of B. And it is one of the problems of C++ that you cannot do the following (in B.h)
class A : public RefCountImpl; // partial forward-declaration, sadly illegal
//
class B
{
// etc
};
So now the solution, assuming that A is not a "known" class but RefCountImpl is (it is defined in SmartPtrT.h) is that you can do this:
class A; // we know it is derived publicly from RefCountImpl
//
class B
{
private:
std::vector< SharedPtr< A, RefCountImpl > > m_VectOfA;
public:
// public interface
};
Note that my AutoPtr class now has a pragma to disable warning 4150. This is so you can use AutoPtr< > for your private (undefined) class members. This is especially useful for the pImpl pattern (known under other names too) where all your implementation is done through a pointer called m_pImpl (or just pImpl).
Although many people know this pattern, they make the mistake of forgetting that use of a member pointer which is created and destroyed by a class requires overloading (or disabling) of the class's copy constructor and assignment. As the AutoPtr class cannot be copied nor can it be assigned from another AutoPtr, you cannot "forget" to do the above. You therefore have to implement deep copy/assignment if you want them. They are now disabled automatically without having to declare them in the private section.
However, my preferred use of AutoPtr is still at local function scope, where you call a function that will create something only for the scope of the function. And you don't want to have to mess about with try..catch and throw.
What you will often find is that your pointer needs to start off as NULL and then get assigned to point to something. Some versions of std::auto_ptr have a "reset" method to change what they point to, but that of VC++ does not. This can obviously be a problem.
The best things come to those who rate
http://www.nmtop40.com/CodeBase/SmartPtrT.h
For one thing I've changed the name of the main class from CSmartPtr to SharedPtr (I don't like the C prefix - and there are different types of smart-pointers. The file has retained its name because it contains other classes too).
One of the significant changes is the second template parameter - which defaults to the first. This, I found, was the solution to my "dependency" problem. The problem is that I had a situation as follows (using the new names):
// file B.h
//
class A;
class B
{
private:
//
std::vector< SharedPtr< A > > m_vectOfA;
public:
// public stuff
};
// file main.cxx
void main()
{
B b;
// do stuff with b
};
The problem was that compiling main.cxx it complained that A was undefined when it tried to call the method Release() in the destructor of B. And it is one of the problems of C++ that you cannot do the following (in B.h)
class A : public RefCountImpl; // partial forward-declaration, sadly illegal
//
class B
{
// etc
};
So now the solution, assuming that A is not a "known" class but RefCountImpl is (it is defined in SmartPtrT.h) is that you can do this:
class A; // we know it is derived publicly from RefCountImpl
//
class B
{
private:
std::vector< SharedPtr< A, RefCountImpl > > m_VectOfA;
public:
// public interface
};
Note that my AutoPtr class now has a pragma to disable warning 4150. This is so you can use AutoPtr< > for your private (undefined) class members. This is especially useful for the pImpl pattern (known under other names too) where all your implementation is done through a pointer called m_pImpl (or just pImpl).
Although many people know this pattern, they make the mistake of forgetting that use of a member pointer which is created and destroyed by a class requires overloading (or disabling) of the class's copy constructor and assignment. As the AutoPtr class cannot be copied nor can it be assigned from another AutoPtr, you cannot "forget" to do the above. You therefore have to implement deep copy/assignment if you want them. They are now disabled automatically without having to declare them in the private section.
However, my preferred use of AutoPtr is still at local function scope, where you call a function that will create something only for the scope of the function. And you don't want to have to mess about with try..catch and throw.
What you will often find is that your pointer needs to start off as NULL and then get assigned to point to something. Some versions of std::auto_ptr have a "reset" method to change what they point to, but that of VC++ does not. This can obviously be a problem.
The best things come to those who rate