-1

I have learned about three cases about calling the copy constructor

1. A variable is being initialized from an object of the same class

2. A function is called with a value parameter of the class

3. A function is returning a value that is an object of the class

Also textbook says for the above two cases(case2 and 3), to avoid calling copy constructors, use call-by-reference

I have searched for some information but I can't understand exactly.

For example(I made my own code)

class CpClass{
    int p;

       CpClass(const CpClass &obj){
           cout<<"user-defined constructor"<<endl;
           p = obj.p; 
       }

       ~CpClass(){
       cout<<"destructor"<<endl;
       }
};

void show1(String &s)
{ cout << "show1 : " << s.p; }
void show2(String s)
{ cout << "show2 : " << s.p; }

 int main(){

 CpClass c1(10);
 CpClass c2(c1);
 show1(c2);
 show2(c2);

  };

I found some information about this.

First, When we pass an argument which is a class object, if the parameter is reference form not value, it does not call the destructor as soon as the function is ended. It calls destructor when the main function is ended

Second, it call constructor when copy argument whether the parameter form is call by value or call by reference(In code, String &s or String s)

Am I correct or not?

cp3
  • 1
  • 2
  • 7
  • 3
    Can you give the real code you used? This is not it. And which compiler with what flags. – Matthieu Brucher Nov 18 '18 at 14:34
  • 1
    Just a side comment: care must be taken when returning objects via references. If the object is created on the stack, then the reference will dangle. See [https://stackoverflow.com/questions/2497541/c-best-practice-returning-reference-vs-object](https://stackoverflow.com/questions/2497541/c-best-practice-returning-reference-vs-object) for details. – eozd Nov 18 '18 at 14:41

1 Answers1

1

As your posted code does not compile I changed it to:

#include <iostream>
using namespace std;

struct CpClass{
    int p;

    CpClass(int i){
        cout<<"user-defined constructor"<<endl;
        p = i; 
    }

    CpClass(const CpClass &obj){
        cout<<"user-defined constructor"<<endl;
        p = obj.p; 
    }

    ~CpClass(){
        cout<<"destructor"<<endl;
    }
};

void show1(CpClass &s)
{ cout << "show1 : " << s.p; }
void show2(CpClass s) { // Constructor
    cout << "show2 : " << s.p; 
} // Destructor for s

int main() {
   CpClass c1(10); // Constructor
   CpClass c2(c1); // Constructor
   show1(c2);
   show2(c2);
   return 0;
}; // Desctructor for c2, c1

Following lines call a constructor

CpClass c1(10);
CpClass c2(c1);

show2(c2);

The first desctructor is called after leaving function

void show2(CpClass s)

The destructors for c2 and c1 are called when leaving main function (in this order)

CpClass &s is syntactic sugar for CpClass * const s. That means that s contains the address of the object and not a copy. Syntactic sugar means that this is a short form and you don't need to dereference.

Thomas Sablik
  • 16,127
  • 7
  • 34
  • 62
  • Do you mean, in case of void show1(CpClass &s), it does not call both copy constructor and destructor? – cp3 Nov 18 '18 at 15:15
  • In case of `void show1(CpClass &s)` no memory is allocated and no object is copied. Only the memory address is copied. So no constructor and no destructor is called. – Thomas Sablik Nov 18 '18 at 15:16
  • Aha, then the copy constructor CpClass(const CpClass &obj) is for calling by value form right? not for address Then, do all copy constructor copy value not address? since copy constructor has parameter form like 'const class_name &object' – cp3 Nov 18 '18 at 15:20
  • A copy contructor is applied when you create an object using another object as in the case of `void show2(CpClass s)`. Internally something like `CpClass s(c2)` happens. – Thomas Sablik Nov 18 '18 at 15:25