复制构造函数被多次调用c ++
copy constructor being called multiple times c++
我正在阅读 tutorialspoint.com http://www.tutorialspoint.com/cplusplus/cpp_copy_constructor.htm
提供的 c++ 复制构造函数教程
在他们的示例代码之一中:
#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 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!
我不明白输出。对我来说,这表明第 1 行调用了普通构造函数,然后第 2 行调用了一个复制构造函数,然后 2*"freeing memory" 为 2 个对象
我认为的输出是:
Normal constructor allocating ptr
Copy constructor allocating ptr.
Length of line : 10
Length of line : 10
Freeing memory!
Freeing memory!
q.1> 为什么最初会多次调用复制构造函数
q.2>4 次 "freeing memory" 中间还有一次,我真的很困惑,你能帮帮我吗?
谢谢
void display(Line obj)
为其参数调用复制构造函数,
您可以使用 const 引用来避免复制 (void display(const Line& obj)
).
这是简单构造的:
Line line1(10);
如您所知,这是调用复制构造函数的地方:
Line line2 = line1;
到目前为止一切顺利。现在看看 display
:
的签名
void display(Line obj);
这就是我们所说的按值传递。传值是一种参数形式,它使传入的对象构造一个新对象。因此,这里的两个调用:
display(line1);
display(line2);
都在调用复制构造函数以将 line1
和 line2
放入函数局部 obj
变量中。
这大致相当于:
// Instead of calling display, this happens instead:
{ // Entering a new scope
Line obj = line1;
cout << "Length of line : " << obj.getLength() << endl;
} // Exiting scope
{ // Entering a new scope
Line obj = line2;
cout << "Length of line : " << obj.getLength() << endl;
} // Exiting scope
obj
现在是它自己的对象,独立于 line1
或 line2
的生命周期,当 obj
超出范围时,就像它在函数结束时,它的析构函数被调用。这将解释对析构函数的四次调用:一次用于原始简单构造的对象 (line1
),一次用于复制构造的对象 (line2
),两次用于两个函数局部 obj
s.
如果您想避免像您在问题中指出的那样复制,请使用 pass-by-reference。
例子是这样的:
第1行(10); // 普通构造函数分配 ptr
第2行=第1行; // 复制构造函数分配 ptr
显示(第1行); /* 复制构造函数分配 ptr,因为函数是这样的:
无效显示(行对象);
例如,这将复制进入方法的对象,就好像它是一个 int 一样。如果要消除这个副本,改为
无效显示(const Line& obj);
其中传递了一个引用。
*/
/* 接下来调用函数并打印
行的长度:10
然后在函数末尾调用副本的析构函数,在它之前 returns.
正在释放内存!
*/
display(line2);/* 接下来用第二个函数调用重复相同的模式:
复制构造函数分配指针。
行的长度:10
正在释放内存!
*/
return 0; /* 最后,line1 和 line2 都被销毁:
正在释放内存!
正在释放内存!
*/
q.1> why copy constructor is called multiple times initially
您呼叫display(line)
、display(line2)
。 void display(Line obj)
被定义为作为参数接收 Line
对象,因此每次调用 display
时,都会为该函数复制该对象(就像您向函数发送整数一样,它value 将被复制,这样如果函数修改了那个整数,它不会影响任何东西,除了函数的范围)。为了减少复制构造函数的数量,你可以将display
定义为void display(Line& obj)
。但是请注意,对 obj
所做的每个修改都会反映在 main()
.
中
q.2>4 times "freeing memory" and that too one in between, I am really
confused, could you help me out.
如您所料两次(一次用于 line
,另一次用于 line2
),另外两次用于复制到 display
函数的对象。一旦display
的流程执行,它会破坏所有的本地对象,函数参数被认为是一个本地对象。
我正在阅读 tutorialspoint.com http://www.tutorialspoint.com/cplusplus/cpp_copy_constructor.htm
提供的 c++ 复制构造函数教程在他们的示例代码之一中:
#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 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!
我不明白输出。对我来说,这表明第 1 行调用了普通构造函数,然后第 2 行调用了一个复制构造函数,然后 2*"freeing memory" 为 2 个对象
我认为的输出是:
Normal constructor allocating ptr
Copy constructor allocating ptr.
Length of line : 10
Length of line : 10
Freeing memory!
Freeing memory!
q.1> 为什么最初会多次调用复制构造函数
q.2>4 次 "freeing memory" 中间还有一次,我真的很困惑,你能帮帮我吗?
谢谢
void display(Line obj)
为其参数调用复制构造函数,
您可以使用 const 引用来避免复制 (void display(const Line& obj)
).
这是简单构造的:
Line line1(10);
如您所知,这是调用复制构造函数的地方:
Line line2 = line1;
到目前为止一切顺利。现在看看 display
:
void display(Line obj);
这就是我们所说的按值传递。传值是一种参数形式,它使传入的对象构造一个新对象。因此,这里的两个调用:
display(line1);
display(line2);
都在调用复制构造函数以将 line1
和 line2
放入函数局部 obj
变量中。
这大致相当于:
// Instead of calling display, this happens instead:
{ // Entering a new scope
Line obj = line1;
cout << "Length of line : " << obj.getLength() << endl;
} // Exiting scope
{ // Entering a new scope
Line obj = line2;
cout << "Length of line : " << obj.getLength() << endl;
} // Exiting scope
obj
现在是它自己的对象,独立于 line1
或 line2
的生命周期,当 obj
超出范围时,就像它在函数结束时,它的析构函数被调用。这将解释对析构函数的四次调用:一次用于原始简单构造的对象 (line1
),一次用于复制构造的对象 (line2
),两次用于两个函数局部 obj
s.
如果您想避免像您在问题中指出的那样复制,请使用 pass-by-reference。
例子是这样的:
第1行(10); // 普通构造函数分配 ptr
第2行=第1行; // 复制构造函数分配 ptr
显示(第1行); /* 复制构造函数分配 ptr,因为函数是这样的:
无效显示(行对象);
例如,这将复制进入方法的对象,就好像它是一个 int 一样。如果要消除这个副本,改为
无效显示(const Line& obj);
其中传递了一个引用。 */
/* 接下来调用函数并打印
行的长度:10
然后在函数末尾调用副本的析构函数,在它之前 returns.
正在释放内存!
*/
display(line2);/* 接下来用第二个函数调用重复相同的模式:
复制构造函数分配指针。
行的长度:10
正在释放内存! */
return 0; /* 最后,line1 和 line2 都被销毁:
正在释放内存!
正在释放内存!
*/
q.1> why copy constructor is called multiple times initially
您呼叫display(line)
、display(line2)
。 void display(Line obj)
被定义为作为参数接收 Line
对象,因此每次调用 display
时,都会为该函数复制该对象(就像您向函数发送整数一样,它value 将被复制,这样如果函数修改了那个整数,它不会影响任何东西,除了函数的范围)。为了减少复制构造函数的数量,你可以将display
定义为void display(Line& obj)
。但是请注意,对 obj
所做的每个修改都会反映在 main()
.
q.2>4 times "freeing memory" and that too one in between, I am really confused, could you help me out.
如您所料两次(一次用于 line
,另一次用于 line2
),另外两次用于复制到 display
函数的对象。一旦display
的流程执行,它会破坏所有的本地对象,函数参数被认为是一个本地对象。