0

I was trying to understand the copy constructor, and read this (https://www.tutorialspoint.com/cplusplus/cpp_copy_constructor.htm) tutorialspoint article about it. However, I'm having trouble understanding when the copy constructor was called in the code below. Doesn't Line line(10) only call the Simple constructor, which then allocates memory for ptr and sets the value at ptr to 10?

Is it because we passed line as an argument to display? So does passing an object as an argument always invoke the copy constructor?

#include <iostream>

using namespace std;

class Line {

   public:
      int getLength( void );
      Line( int len );             // simple constructor
      Line( const Line &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 &obj) {
   cout << "Copy constructor allocating ptr." << endl;
   ptr = new int;
   *ptr = *obj.ptr; // copy the value
}

Line::~Line(void) {
   cout << "Freeing memory!" << endl;
   delete ptr;
}

int Line::getLength( void ) {
   return *ptr;
}

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

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

   display(line);

   return 0;
}

Which prints out:

Normal constructor allocating ptr
Copy constructor allocating ptr.
Length of line : 10
Freeing memory!
Freeing memory!
  • 2
    When you call `display(Line obj)`, you copy the `Line` obj into the function argument. – Mansoor Feb 10 '21 at 23:37
  • So does passing an object as an argument always invoke the copy constructor? – inquisitivemongoose Feb 10 '21 at 23:37
  • 3
    @inquisitivemongoose It's somewhat more complicated from C++11. If you have argument passed by value, and you call the function with lvalue, it will be copied. If you call the function with rvalue, it will be moved. If you pass argument by reference, it will never be copied nor moved. – Yksisarvinen Feb 10 '21 at 23:39
  • 2
    Side note: [Compiler am smart](https://en.cppreference.com/w/cpp/language/as_if). It can do whatever it wants to your code so long as you can't see a difference in the behaviour. General rule of thumb: Don't think of your code as a list of instructions, think of it as a description of program behaviour. The compiler's job is to take that behavior and create an efficient set of instructions to produce the described behaviour. – user4581301 Feb 10 '21 at 23:49
  • 1
    Passing an object *by copied value* invokes the copy constructor, or the move constructor (for an rvalue argument that can be moved). – Eljay Feb 10 '21 at 23:55

1 Answers1

2

Doesn't Line line(10) only call the Simple constructor

Yes.

Is it because we passed line as an argument to display?

Yes.

So does passing an object as an argument always invoke the copy constructor?

Not necessarily. For example, some types don't have constructors so copying them won't invoke a constructor. Furthermore, if you pass an rvalue, then move constructor may be invoked instead. Or if the type of the argument is different from the type of the parameter, then a converting constructor or conversion operator may be invoked.

If the parameter is a reference (of same type, so no conversion is involved), then no constructor is invoked.

user4581301
  • 33,082
  • 7
  • 33
  • 54
eerorika
  • 232,697
  • 12
  • 197
  • 326