Два случая, которые следует избегать вызова конструктора копирования

Я узнал о трех случаях вызова конструктора копирования

1. Переменная инициализируется из объекта того же класса

2. Функция вызывается с параметром значения класса

3. Функция возвращает значение, которое является объектом класса

Также в учебнике сказано, что для двух вышеупомянутых случаев (case2 и 3), чтобы избежать вызова конструкторов копирования, используйте call-by-reference

Я искал некоторую информацию, но не могу точно понять.

Например (я сделал свой собственный код)

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);

  };

Я нашел некоторую информацию об этом.

Во-первых, когда мы передаем аргумент, который является объектом класса, если параметр является ссылочной формой, а не значением, он не вызывает деструктор, как только функция завершается. Вызывает деструктор, когда основная функция заканчивается

Во-вторых, он вызывает конструктор, когда копирует аргумент, является ли форма параметра вызовом по значению или вызовом по ссылке (в коде, String &s или String s)

Я прав или нет?

1 ответ

Поскольку ваш опубликованный код не компилируется, я изменил его на:

#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

Следующие строки вызывают конструктор

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

show2(c2);

Первый дескриптор вызывается после выхода из функции

void show2(CpClass s)

Деструкторы для c2 а также c1 называются при выходе main функция (в этом порядке)

CpClass &s является синтаксическим сахаром для CpClass * const s, Это означает, что s содержит адрес объекта, а не копию. Синтаксический сахар означает, что это короткая форма, и вам не нужно разыменовывать.

Другие вопросы по тегам