C++ 解释复制构造函数示例

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12099792/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 15:52:37  来源:igfitidea点击:

Explaining copy constructor example

c++oopcopy-constructor

提问by Omar

A copy constructor is used for many things such as when I need to use pointers or dynamically allocate memory for an object. But looking at this example at tutorialpoint.com:

复制构造函数用于许多事情,例如当我需要使用指针或为对象动态分配内存时。但是看看这个例子tutorialpoint.com

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

the result is :

结果是:

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

and when I commented out (the copy constructor) and the code inside destructor I got the same results:

当我注释掉(复制构造函数)和析构函数中的代码时,我得到了相同的结果:

Normal constructor allocating ptr
Length of line : 10

So what is the difference between using the copy constructor here or not? Also why does "Freeing Memory!" occur twice?

那么在这里使用与不使用复制构造函数有什么区别呢?还有为什么“释放内存!” 出现两次?

采纳答案by Pete Becker

The argument to the display()function is passed by value, so the compiler calls the copy constructor to create it. When the class defines its copy constructor you get the correct semantics: the copy constructor makes a copy, and that copy has its own memory to hold the length. When you remove the copy constructor, the compiler generates one for you, and the copy that gets passed to display()has the same pointer as the original. When that copy gets destroyed it deletes the memory that ptr points to. When the original gets destroyed it deletes the same memory again (which happens to have no visible effects here). That's definitely not what you want to have happen, which is why you need to define a copy constructor. As @Joe says: inside the destructor, print the value of `ptr' to see this more clearly.

display()函数的参数是按值传递的,因此编译器调用复制构造函数来创建它。当类定义其复制构造函数时,您将获得正确的语义:复制构造函数生成一个副本,并且该副本拥有自己的内存来保存长度。当您删除复制构造函数时,编译器会为您生成一个,并且传递给的副本display()与原始副本具有相同的指针。当该副本被破坏时,它会删除 ptr 指向的内存。当原始被破坏时,它会再次删除相同的内存(这恰好在这里没有可见的影响)。这绝对不是您想要发生的事情,这就是您需要定义复制构造函数的原因。正如@Joe 所说:在析构函数中,打印 `ptr' 的值以更清楚地看到这一点。

回答by Joe

Print the address of the memory being freed.

打印被释放的内存地址。

I believe you will find the compiler generated the constructor for you, did a value copy of the contents, including the pointer, and you are double-freeing the pointer and just getting lucky that the runtime isn't complaining about it.

我相信您会发现编译器为您生成了构造函数,对内容(包括指针)进行了值复制,并且您正在双重释放指针,并且很幸运运行时没有抱怨它。

The compiler generated copy constructor is still being called - nothing has changed in that regard, you just aren't printing anything from it since you didn't write it.

编译器生成的复制构造函数仍在被调用 - 在这方面没有任何变化,因为您没有编写它,所以您没有从中打印任何内容。

回答by Raja

If we don't define our own copy constructor, the C++ compiler creates a default copy constructor for each class which does a member wise copy between objects. The compiler created copy constructor works fine in general. We need to define our own copy constructor only if an object has pointers or any run time allocation of resource like file handle, a network connection..

如果我们不定义自己的复制构造函数,C++ 编译器会为每个类创建一个默认的复制构造函数,它在对象之间进行成员明智的复制。编译器创建的复制构造函数通常工作正常。仅当对象具有指针或任何运行时资源分配(如文件句柄、网络连接)时,我们才需要定义自己的复制构造函数。

回答by Abdul Rahman Sajjad

A constructor of some type T of the form

某种类型 T 的构造函数

T (const & T);

The single argument must be a const reference to an existing object of same type Creates a duplicate of the existing object Used whenever a copy of an object is needed Including arguments to functions, results returned from functions Problems with pointer-based arrays in C++:– No range checking. Cannot be compared meaningfully with == No array assignment (array names are const pointers). If array passed to a function, size must be passed as a separate argument.

单个参数必须是对相同类型的现有对象的 const 引用 创建现有对象的副本 在需要对象副本时使用 包括函数的参数、函数返回的结果 C++ 中基于指针的数组的问题:–没有范围检查。无法与 == 无数组赋值进行有意义的比较(数组名称是常量指针)。如果数组传递给函数,则大小必须作为单独的参数传递。