The problem when using default copy constructor is if the source contains any pointer types then the destination also points to the same address . So when the source object goes out of scope , deferencing the pointer type from the destination results in Segfault . So that’s why we override the default copy constructor in most cases. Now in high performance application creating a new object in the copy constructor seriously hinders performance . So instead of creating object , the pointer in destination object is just made to point the source object pointer until & unless you want to perform a write action on the object . I’m posting the code which was causing some Segfaults in the destructor and was a pain the ass . Finally it’s corrected . I guess you will enjoy the beauty of c++ and appreciate it’s elegance and power .
#include<iostream>
#include<cstring>
using namespace std;
class Dog
{
string name;
int count;
public:
Dog(string _name):name(_name),count(1)
{
cout<<name<<":: The count value is "<<count<<endl;
}
Dog ( Dog & ob):name(ob.name),count(1)
{
cout<<name<<":: The count value is "<<count<<endl;
}
void Attach()
{
count++;
cout<<name<<":: The count value is "<<count<<endl;
}
void Deattach()
{
count -- ;
cout<<name<<":: The count value is "<<count<<endl;
if( count ==0)
{
cout<<name<<":: Deleted object"<<endl;
delete this;
}
}
Dog* Alias()
{
if( count ==1 )
return this;
else
return new Dog(*this);
}
void Setname(string _name)
{
name=_name;
}
};
class Doghouse
{
Dog *dog;
string house_name;
public:
Doghouse(string _house_name)
{
house_name=house_name;
}
Doghouse(Dog *_dog, string _house_name):dog(_dog),house_name(_house_name){
cout<<"The house name is "<<house_name<<endl;
}
Doghouse(Doghouse & dh)
{
house_name=dh.house_name;
dog=dh.dog;
dog->Attach();
}
Doghouse& operator = (const Doghouse& dh)
{
dog->Deattach();
dog=dh.dog;
house_name=dh.house_name;
dog->Attach();
}
void Alias()
{
dog=dog->Alias();
}
void rename_dog(string _name)
{
Alias();
dog->Setname(_name);
}
~Doghouse()
{
dog->Deattach();
}
};
int main()
{
Dog *d1=new Dog("Peggy");
Dog *d2=new Dog("Hussky");
Doghouse dh(d1,"kennel");
Doghouse dh1=dh;
Doghouse dh2(d2,"kennel2");
dh2=dh1;
dh2.rename_dog("husskie");
}
Posted by Anish on November 25, 2010 at 4:48 am
Hey, Nice post.I am not very clear on this idea, I have one doubt that is, when you copy only on a write still segfault might happen right?
For instance, object B has a pointer that is pointing to a data of object A. Before you write a value to B (only when you will create a copy) if you delete A, then the subsequent write might cause a segfault. Am I right?
Posted by abhi74k on November 25, 2010 at 9:32 am
Thanks … Suppose when both A & B point to an object and if i delete A then i just decrement the reference counter without deallocating space for it . Just like count variable in inode block . Only when one pointer is pointing to object i actually dellocate space for the object .
Posted by Anish on November 25, 2010 at 11:14 am
Aha nice…now I get it.
Posted by Biswabandan on November 25, 2010 at 3:26 pm
nice explanation
Posted by abhi74k on November 25, 2010 at 3:48 pm
Thanks biswa