我在网上找到了这段代码:
#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!
我无法理解为什么在没有作为参数传递给复制构造函数的对象时调用复制构造函数? 另外,在调试时,我理解在函数main完成后调用析构函数。为什么它被调用以及为什么它在函数main终止后被调用? 感谢,
答案 0 :(得分:5)
void display(Line obj) {
此函数按值获取其参数。这意味着将此参数传递给此函数将复制它。当main()
调用display()
时,这就是调用复制构造函数的地方。
如果您更改此功能,以便通过引用获取其参数:
void display(Line &obj) {
您将发现不再从示例程序中调用复制构造函数。
您可以在C ++手册中找到有关按值与参考传递参数的更多信息。
答案 1 :(得分:1)
函数显示按值获取参数,因此调用复制构造函数。如果不需要,请通过引用传递 - Line&amp; OBJ。更好的是,通过const引用来调用它 - const Line&amp; OBJ。但在后一种情况下,你在显示内部调用的成员函数也必须是const。
答案 2 :(得分:0)
display()
中的论点:
void display(Line obj)
调用复制构造函数,因为在函数的参数中创建了一个新对象。因此,传递给此函数的任何类Line
的对象都将被复制并用作函数体的参数。
您可以在以下行中调用此函数:
display(line);
因此,line
的副本在display()
中生成。为避免这种情况,请改为引用类Line
的对象。将参数在函数头中传递的方式更改为:
void display(Line &obj)
这样,您只是引用该对象,因此,不会复制它。因此,此处不会调用复制构造函数。