Hi ,
Below is the code of template smart point implementation. in below code snippet we are not allocating any memory in smart pointer constructer for ptr but still delete is called in destructor for ptr. Is it right way to implement the same ?
can we delete the pointer which was never been allocated in constructor.

#include<iostream>
using namespace std;

// A generic smart pointer class
template <class T>
class SmartPtr
{
   T *ptr;  // Actual pointer
public:
   // Constructor
   explicit SmartPtr(T *p = NULL) { ptr = p; }

   // Destructor
   ~SmartPtr() { delete(ptr); }

   // Overloading dereferncing operator
   T & operator * () {  return *ptr; }

   // Overloding arrow operator so that members of T can be accessed
   // like a pointer (useful if T represents a class or struct or 
   // union type)
   T * operator -> () { return ptr; }
};

int main()
{
    SmartPtr<int> ptr(new int());
    *ptr = 20;
    cout << *ptr;
    return 0;
}

There are a number of errors in this code. Nothing major, but a lot of things for you to think about...

    #include <iostream>
    using namespace std;
    // A generic smart pointer class
    template <class T> class SmartPtr
    {
       T *ptr;  // Actual pointer
    public:
       // Constructor
       SmartPtr(T* p = NULL) : ptr(p) {}
       // Destructor
       ~SmartPtr() { delete(ptr); }
       // Overloading dereferncing operator
        const T& operator*() const
        {
            if (!ptr) // throw exception
            else
                return *ptr;
        }
      T& operator*()
        {
            if (!ptr) // throw exception
            else
                return *ptr;
        }
       // Overloding arrow operator so that members of T can be accessed
       // like a pointer (useful if T represents a class or struct or 
       // union type)
       const T* operator->() const { return ptr; }
       T* operator->() { return ptr; }
    };

    int main()
    {
        SmartPtr<int> ptr(new int());
        *ptr = 20;
        cout << *ptr;
        return 0;
    }
  1. Your contents-of operator should have two methods. One is a const method that returns a const reference to the member. The other would be as you did, which is non-const. If it doesn't throw an exception, then you can set the value as shown in main(). See my additions/changes above.
  2. If you have the appropriate setter method, then you can create a pointer to the integer and set it accordingly, or if it already exists you can reset the value as specified.

So, your main problem is that you have not dealt with the possibility of a null pointer to the item. Also, you are not dealing with reference counting. What happens if the actual item pointer is assigned to another "smart" pointer? One goes out of scope and the internal item is deleted, but another smart pointer is still holding onto it... Crash! Bang! Boom!

Real smart pointers are not simple. I have implemented such for major commercial system software. 10+ million lines of code, no deletes, and no memory leaks, AND it deals with recursive network structures. These are called reference counting garbage collectors. The smart pointers are a small part of that.

Finally, rather than throwing an exception in the getter methods, you can create a new object and assign a reasonable value to it. This would work for scalar types (int, float, char, etc), but not for more complex objects. This is a topic for a future exercise - how to initialize a new object when you don't know what a "sane" value for it may be. Complex objects may have default constructors. Others may not. What about singleton classes? What about floating point values where an item constructed on the stack or on the heap may contain a value that is considered NAN (Not-A-Number)? I think throwing an exception when the ptr type has not been allocated would be preferable. At least, more predictable!

Edited 1 Year Ago by rubberman

As for your question: Is it right way to implement the same ?
can we delete the pointer which was never been allocated in constructor?

The answer to this is that when you assign an object to a smart pointer, it's ownership is passed to the smart pointer. Caveat. If the object is on the stack and not the heap, then you need to make a copy of it, otherwise "bad things" will happen! So, you may want to have another constructor that takes a reference to the object. When that happens, you can create a copy easily enough. The caller doesn't need to worry about it. The purpose of this stuff, and application development frameworks in general, is that the user of the framework should not have to be to cognizant of how the framework works. They should be able to concentrate on their domain and not worry about what is going on "under the covers". Example:

       SmartPtr(const T& theObj) : ptr(NULL)
       {
          ptr = new T(theObj);
       }

Or:

       SmartPtr(const T& theObj) : ptr(new T(theObj)) {}

Edited 1 Year Ago by rubberman

Thanks rubberman for your replay . I didn't share entire smart pointer implementation as it won't help me to focus on question which is related only construction and destructionof object.

SmartPtr(T* p = NULL) : ptr(p) {}
10.       // Destructor
11.       ~SmartPtr() { delete(ptr); }

why it is not written like:

SmartPtr(T* p = NULL) : ptr  (new (p)) {}
10.       // Destructor
11.       ~SmartPtr() { delete(ptr); }

usually if we allocate the memory in constructor then only object can be deleted in destructor.

This article has been dead for over six months. Start a new discussion instead.