Go4Expert

Go4Expert (http://www.go4expert.com/)
-   C++ (http://www.go4expert.com/articles/cpp-tutorials/)
-   -   The copy constructor: Object initialization (http://www.go4expert.com/articles/copy-constructor-object-initialization-t2069/)

rahulnaskar 30Nov2006 11:32

The copy constructor: Object initialization
 
1 Attachment(s)

Introduction



Memory allocation for objects is a tough issue, sometimes. Dynamically allocated memory has to be treated specially when one object is used to initialize another. In default constructor a bit wise copy is done when one object is assigned to another, leaving no room for separate memory allocation and hence copy constructor.

Consider the class:
Code: CPP

class clsString
{
private:
int lenName;    //Length of the string, not required for dynamic memory allocation
char *strName;  //The string, required to have dynamic memory allocation
public:
    //The constructor where memory is allocated
    clsString(char *s="")
    {
        lenName = strlen(s)+1;
        strName = new char[lenName]; //Dynamic allocation
        strcpy(strName,s);
    }
    //Destructor where memory is freed
    ~clsString() {cout << "In destructor Name is " << strName << " and length is " << lenName << endl; delete[] strName;}
    //Returns the value where data is stored in allocated memory
    char * getName() {return strName;}
    //Returns the value where data is stored not by allocating memory
    int getLen() {return lenName;}
};

Using the code ...



The constructor is default and strip of memory is allocated, which is also destructed during deallocation of the memory. When one object of this class is used to initialize another object of the type, we have a serious problem. The problem is that both the objects will be pointing to the same memory location belonging to the data member strName. When one object is destructed the other one will be pointing to a portion of memory, which has already been freed and will generate a run-time error.

Consider using the class in the following way:
Code: CPP

int main()
{
    //Explicit initialization
    clsString myName("Bill Gates");
    //Initialization by existing object
    clsString myDuplName=myName;
    //Object 1 data
    cout << "Initial Object Name: " << myName.getName() << endl;
    cout << "Initial Object Length: " << myName.getLen() << endl;
    //Object 2 data
    cout << "Copied Object Name: " << myDuplName.getName() << endl;
    cout << "Copied Object Length: " << myDuplName.getLen() << endl;
    cout << "---------------------------" << endl;
    cout << "---------------------------" << endl;
    return 0;
}

Note: When run from MS VC 6 IDE, you will notice an error when the destructor is called for the second time. It will try to free a memory location which has already been freed and hence the error.

Try testing the results by copying the code, pasting it in a new project and running the same.

The resolution:



Copy constructors should be used in cases similar to these to avoid the problem mentioned. Consider using the same class with copy constructor attached along with the default constructor.

Code: CPP

class clsString
{
private:
    int lenName;    //Length of the string, not required for dynamic memory allocation
    char *strName;  //The string, required to have dynamic memory allocation
public:
    //The constructor where memory is allocated
    clsString(char *s="")
    {
        lenName = strlen(s)+1;
        strName = new char[lenName];
        strcpy(strName,s);
    }
    //The copy constructor
    clsString (const clsString& t)
    {
        lenName = t.lenName;
        strName = new char[lenName];
        strcpy(strName,t.strName);
    }
    //Destructor where memory is freed
    ~clsString() {cout << "In destructor Name is " << strName << " and length is " << lenName << endl; delete[] strName;}
    //Returns the value where data is stored in allocated memory
    char * getName() {return strName;}
    //Returns the value where data is stored not by allocating memory
    int getLen() {return lenName;}
};

When this piece of code is used no error is generated. During initializing the existing object is passed as the parameter to the copy constructor, which is a const. Reallocate your necessary memory and all those stuff you require without disturbing any existing objects by the copy constructor.

Copy constructors have the same effects when an object is passed on as a function parameter or is returned by a function. I will probably write on both of them in my coming article.

Try tweaking around the code attached.

rahul.mca2001 6Mar2008 13:55

Re: The copy constructor: Object initialization
 
nice code


All times are GMT +5.5. The time now is 16:37.