View Full Version: copy constructor, this pointer, and polymorphism?

C++ Learning Community > C++ Tips > copy constructor, this pointer, and polymorphism?


Title: copy constructor, this pointer, and polymorphism?
Description: need a little help with those


yahn - November 20, 2005 03:11 PM (GMT)
i read about.com's c++ tutorial and I learned how most of the language works. however i don't really understand the copy constructor, the uses for the this pointer, and how polymorphism works. if anyone could direct me to a place with a good tutorial on those subjects i'd appreciate it. thank you for your time.

myork - November 20, 2005 04:23 PM (GMT)
QUOTE (yahn @ Nov 20 2005, 10:11 AM)
i read about.com's c++ tutorial and I learned how most of the language works.  however i don't really understand the copy constructor, the uses for the this pointer, and how polymorphism works.  if anyone could direct me to a place with a good tutorial on those subjects i'd appreciate it.  thank you for your time.


<SARCASM>
So basically you don't understand the reason for C/C++
</SARCASM>

Come it's Sunday morning I'am allowed to be a little sarcastic :-)

Copy Constructor
I assume you understand a constructor (To make sure an object is in a valid state).

A copy constructor is basically a constructor.
The difference it gets its initial state by copying another object.

CODE
int x(5);  // Here x is constructed. The int constructor initialises the value of x to 5.
int y(x);  // Here y is constructed. The int constructor initialises the value of y using x.

NB int do not have real constructors but the principle is the same.


A more complex example of a copy constructor:

CODE

class MySimpleString
{
   public:
       ~MySimpleString() { delete [] val;}
       MySimpleString()                            // DefaultConstructor
       {   init("");}
       MySimpleString(const char* s)                // Normal constructor.
       {   init((s == NULL)?"":s);}
       MySimpleString(const MySimpleString& copy)  // Copy Constructor
       {   init(copy.val);}
       MySimpleString& operator=(const MySimpleString& copy) // Assignment operator
       {   delete [] val;init(copy.val);return(*this);}
   private:
       void init(const char* copy)  // Only to be used by if val is undefined.
       {   val = new char[strlen(copy) + 1];
           strcpy(val,copy);
       }
       char* val;
}


In this code each instance of MySimpleString has its own copy of the string (no sharing is allowed). The copy constructor in this case makes sure that we copy the string from the object 'copy' into this object so we have our own copy. If the copy constructor just did
CODE
val = copy.val;
it would look like we had done the same thing. But both the destructors would delete the same pointer and this is bad.

The reason we must have a copy constructor here is because if we do not define one then the compiler automatically generates a default copy constructor and assignment operator for us (behind the senes so to say). The default Copy Constructor does a shallow copy. Or
CODE
val = copy.val;
Which as explained above is bad.


The this Pointer
It is basically a pointer to yourself. So what is it good for.
You need to use it when calling virtual functions on yourself.


CODE
class Farm;
class Animal
{
   public:
       virtual void makeNoise() {std::cout << "??????";}
       void sendToFarm(Farm* f); //
       void chat()
       {
           makeNoise();          // Calling makeNoise() like this calls your local copy of makeNoise()
           this->makeNoise();    // Calling makeNoise() like this calls the virtual copy of makeNoise()
       }
};

class Pig: public Animal
{
   public:
       virtual void makeNoise() {std::cout << "OINK";}
};


int main(int argc,char* argv[])
{
   Pig       p;
   p.chat();
}


Also 'this' is usefull if you want to send a pointer to yourself to another object.
CODE
class Farm
{    public: addAnimal(Animal* animal);
};
void Animal::sendToFarm(Farm *f)
{
   f->addAnimal(this);
}



polymorphism
This is the ability of objects to act deferently depending on their type.
In the Animal example above I defined Pig that goes 'OINK'.
If I define another type 'Sheep' and override the method makeNoise() the objects are now acting polymorphically as the call to the function makeNoise() will do different things depending on the type of the object. All the compiler has to know is that the object is an Animal.

CODE

class Sheep: public Animal
{
   public:
       virtual void makeNoise() {std::cout << "BAAA";}
};

void polymorphismHandleAnimalNoise(Animal& animal)
{
   animal.makeNoise(); // polymorphic call to makeNoise();
}

ramirez - November 20, 2005 05:25 PM (GMT)
Just a little fix if you want to try myork's code:
CODE
void polymorphismHandleAnimalNoise(Animal& animal)
{
  animal->makeNoise(); // polymorphic call to makeNoise();
}

The function should either take a pointer for its argument, or use animal.makeNoise(); ( . instead of -> ) to call the function.

C-Man - November 21, 2005 08:53 AM (GMT)
ramirez it's a reference not a pointer how can you use -> O.o

ramirez - November 21, 2005 01:08 PM (GMT)
Read what I said. :p
QUOTE
The function should either take a pointer for its argument, or use animal.makeNoise(); ( . instead of -> ) to call the function.


EDIT: I understand your confusion.
myork originally used ->, the code I quoted was his, but he fixed it without posting anything.

AquaFox - November 21, 2005 02:09 PM (GMT)
QUOTE (ramirez @ Nov 21 2005, 01:08 PM)
myork originally used ->, the code I quoted was his, but he fixed it without posting anything.

I guess Myork hides it quick... An expert with alot of experience doesn't want to be embarresed :P.

C-Man - November 21, 2005 02:13 PM (GMT)
lol i though rami had a moment of temporary insanity :P




Hosted for free by InvisionFree