1

To understand working of constructor, copy constructor, destructor, I wrote the following code.

#include <iostream>
 using namespace std; 
 class Cat
{
 public:
  Cat();
  Cat(Cat&);
  ~Cat();
  int itsage;
};
 
 Cat::Cat()
{
 cout << "Constructor called\n";
 cout << this << endl;
 itsage=2;
}
 
 Cat::Cat(Cat& theCat)
{
 cout << "Copy constructor called\n";
 cout << this << endl;
 itsage=theCat.itsage;
}

 Cat::~Cat()
{
 cout << "Destructor called\n";
 cout << this << endl;
}
 
 Cat myFunction(Cat Frisky)
{
 cout << "Inside myFunction\n";
 cout << "Frisky's address : " << &Frisky ; 
 cout << "\nFrisky's age: " << Frisky.itsage << "\n";
 Frisky.itsage=100;
 cout << "Reassigned Frisky's age: "<< Frisky.itsage << "\n";
 return Frisky;
}
 
 int main()
{
 Cat Mani;
 cout << "Mani's address : " << &Mani ;
 cout << "\nMani's age: " << Mani.itsage << "\n";
 myFunction(Mani);
 return 0;
}

I got output as follows:

Constructor called
0x61ff04
Mani's address : 0x61ff04
Mani's age: 2
Copy constructor called
0x61ff0c
Inside myFunction
Frisky's address : 0x61ff0c
Frisky's age: 2
Reassigned Frisky's age: 100
Copy constructor called
0x61ff08
Destructor called
0x61ff08
Destructor called
0x61ff0c
Destructor called
0x61ff04

Everything is ok to me except what is stored at address 0x61ff08 when there was second call to copy constructor? Means we can see what is stored at addresses 0x61ff0c and 0x61ff04 which are nothing but Frisky and Mani. Then what is that invisible thing at 0x61ff08?

I thought of making that object visible by making a small change in main function.

#include <iostream>
 using namespace std; 
 class Cat
{
 public:
  Cat();
  Cat(Cat&);
  ~Cat();
  int itsage;
};
 
 Cat::Cat()
{
 cout << "Constructor called\n";
 cout << this << endl;
 itsage=2;
}
 
 Cat::Cat(Cat& theCat)
{
 cout << "Copy constructor called\n";
 cout << this << endl;
 itsage=theCat.itsage;
}

 Cat::~Cat()
{
 cout << "Destructor called\n";
 cout << this << endl;
}
 
 Cat myFunction(Cat Frisky)
{
 cout << "Inside myFunction\n";
 cout << "Frisky's address : " << &Frisky ; 
 cout << "\nFrisky's age: " << Frisky.itsage << "\n";
 Frisky.itsage=100;
 cout << "Reassigned Frisky's age: "<< Frisky.itsage << "\n";
 return Frisky;
}
 
 int main()
{
 Cat Mani;
 cout << "Mani's address : " << &Mani ;
 cout << "\nMani's age: " << Mani.itsage << "\n";
 Cat Sweety = myFunction(Mani); 
 cout << "Sweety's age : " << Sweety.itsage ;
 return 0;
}

But received an error as follows :

ppp.cpp: In function 'int main()':
ppp.cpp:47:25: error: invalid initialization of non-const reference of type 'Cat&' from an rvalue of type 'Cat'
  Cat Sweety = myFunction(Mani);
               ~~~~~~~~~~^~~~~~
ppp.cpp:19:2: note:   initializing argument 1 of 'Cat::Cat(Cat&)'
  Cat::Cat(Cat& theCat)
  ^~~

I really didn't get what went wrong.

Believer
  • 261
  • 1
  • 8

2 Answers2

0

Your first code returns a copy of Frisky from myFunction, that is where the additional copy comes from.

Your second code doesn't work because your copy constructor erroneously takes a non-const reference and you can't pass the temporary value returned from myFunction to a non-const reference.

Not directly related to your question but you should obey the rule of three and implement the assignment operator too.

Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
  • Bit strange.. when we pass ```Mani ```, it was ok to copy constructor but when we return ```Frisky``` it had problem.. why so? – Believer Aug 28 '20 at 17:23
  • Mani isn't a temporary so can be bound to a non-const reference – Alan Birtles Aug 29 '20 at 05:00
  • Thanks.. one last thing.. may sound ugly but I had this doubt for some time in my mind.. copy of ```Frisky``` is stored at ```0x61ff08```and later it also got destroyed.. then what abt copy of ```Mani``` (which was created when we made call to ```myFunction```).. doesn't it get stored somewhere or destroyed? – Believer Aug 29 '20 at 06:44
  • The copy of Mani is Frisky, it's stored on the stack of `myFunction` and is destroyed at the end of the function – Alan Birtles Aug 29 '20 at 07:36
0
Cat(Cat &);

Use const here.

Cat(const Cat &);

Not related but consider using initialisation like this.

Cat Sweety{myFunction(Mani)};
puio
  • 1,208
  • 6
  • 19