【问题标题】:Why is the copy constructor called after the simple constructor is called? [duplicate]为什么调用简单构造函数后调用复制构造函数? [复制]
【发布时间】:2021-05-14 17:19:42
【问题描述】:

我试图理解复制构造函数,并阅读了这篇关于它的 (https://www.tutorialspoint.com/cplusplus/cpp_copy_constructor.htm) 教程点文章。但是,我无法理解何时在下面的代码中调用了复制构造函数。 Line line(10) 不是只调用 Simple 构造函数,然后为 ptr 分配内存并将 ptr 的值设置为 10?

是因为我们将 line 作为参数传递给 display 吗?那么将对象作为参数传递是否总是调用复制构造函数?

#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;
}

打印出来的:

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

【问题讨论】:

  • 调用display(Line obj) 时,会将Line obj 复制到函数参数中。
  • 那么传递一个对象作为参数总是调用复制构造函数吗?
  • @inquisitivemongoose 从 C++11 开始有点复杂。如果您有按值传递的参数,并且您使用左值调用该函数,它将被复制。如果您使用右值调用该函数,它将被移动。如果您通过引用传递参数,它将永远不会被复制或移动。
  • 旁注:Compiler am smart。只要您看不到行为的差异,它就可以对您的代码执行任何操作。一般经验法则:不要将您的代码视为指令列表,而应将其视为对程序行为的描述。编译器的工作是接受该行为并创建一组有效的指令来产生所描述的行为。
  • 传递对象通过复制值调用复制构造函数,或移动构造函数(对于可以移动的右值参数)。

标签: c++


【解决方案1】:

不是 Line line(10) 只调用 Simple 构造函数

是的。

是因为我们将 line 作为参数传递给 display 吗?

是的。

那么将对象作为参数传递是否总是调用复制构造函数?

不一定。例如,某些类型没有构造函数,因此复制它们不会调用构造函数。此外,如果您传递一个右值,则可能会调用移动构造函数。或者,如果实参的类型与形参的类型不同,则可以调用转换构造函数或转换运算符。

如果参数是引用(类型相同,因此不涉及转换),则不调用构造函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-28
    • 2012-07-08
    • 1970-01-01
    • 2021-02-18
    • 2014-01-14
    • 1970-01-01
    • 2015-06-10
    相关资源
    最近更新 更多