Конструктор копирования C вызывается несколько раз

#c #constructor #copy-constructor

#c #конструктор #конструктор копирования

Вопрос:

Я пытался понять основы конструкторов копирования и наткнулся на следующий пример.

 #include <iostream>

using namespace std;

class Line
{
   public:
      int getLength() const;
      Line( int len );             // simple constructor
      Line( const Line amp;obj);  // copy constructor
      ~Line();                     // destructor

   private:
      int *ptr;
};

// Member functions definitions including constructor
Line::Line(int len)
{
    cout << "Normal constructor allocating ptr" << endl;
    // allocate memory for the pointer;
    ptr = new int;
    *ptr = len;
}

Line::Line(const Line amp;obj)
{
    cout << "Copy constructor allocating ptr." << endl;
    ptr = new int;
   *ptr = *obj.ptr; // copy the value
}

Line::~Line()
{
    cout << "Freeing memory!" << endl;
    delete ptr;
}
int Line::getLength() const
{
    return *ptr;
}

void display(Line obj)
{
   cout << "Length of line : " << obj.getLength() <<endl;
}

// Main function for the program
int main( )
{
   Line line1(10);

   Line line2 = line1; // This also calls copy constructor

   //display(line1);
   //display(line2);

   return 0;
}
 

При выполнении он выдает следующий результат.

 Normal constructor allocating ptr
Copy constructor allocating ptr.
Copy constructor allocating ptr.
Length of line : 10
Freeing memory!
Copy constructor allocating ptr.
Length of line : 10
Freeing memory!
Freeing memory!
Freeing memory!
 

Конструктор копирования вызывается только один раз, в Line line2 = line1; Но кажется, что конструктор копирования вызывается дважды. Поэтому я прокомментировал
display(line1); и display(line2); . После этого вывод выглядит примерно так.

 Normal constructor allocating ptr
Copy constructor allocating ptr.
Freeing memory!
Freeing memory!
 

Итак, проблема (я не знаю, следует ли мне называть это проблемой или стандартом по умолчанию в C ) связана с функцией отображения. Может быть, это связано с тем, что функция display() автоматически создает копию объекта, который он обрабатывает, и поэтому конструктор копирования вызывается дважды для каждого экземпляра? Пожалуйста, уточните. Спасибо.

Ответ №1:

с void display(Line obj) помощью вы передаете объект по значению, поэтому создаете копию.

Вы должны передавать по (const) ссылке, чтобы избежать копий:

 void display(const Lineamp; obj)
 

Комментарии:

1. OP также должен постоянно корректировать свои функции -члены, если они используют a const amp; .

2. Выдает следующую ошибку. main.cpp: In function ‘void display(const Lineamp;)’: main.cpp:45:49: error: passing ‘const Line’ as ‘this’ argument of ‘int Line::getLength()’ discards qualifiers [-fpermissive] cout << "Length of line : " << obj.getLength() <<endl;

3. @NathanOliver, @shiladityabasu: Действительно, я исправил код OP для getLengh() .

Ответ №2:

Может быть, это связано с тем, что функция display() автоматически создает копию объекта, который он обрабатывает, и поэтому конструктор копирования вызывается дважды для каждого экземпляра? Пожалуйста, уточните. Спасибо.

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