最近在学习C++的类如何构造,在W3Cschool上看到关于拷贝构造函数的一个例子,记录一下。
这篇文章大致是构造了如下的一个Line
类:
class Line{ public: int getLength(void); Line(int len); // 简单构造函数 Line(const Line &obj); // 拷贝构造函数 ~Line(); // 析构函数 private: int *ptr; //指向length };
其中构造函数和析构函数的定义如下:
Line::Line(int len){ cout<< "Normal constructor allocating ptr." <<endl; // 为指针分配内存 ptr = new int; *ptr = len; }
Line::Line(const Line &obj){ cout<< "Copy constructor allocating ptr." <<endl; ptr = new int; // copy the value //这里右式的运算顺序是先获取obj.ptr,再用'*'取值. //因为是复制值,而不是复制地址,所以'='两边都要加上'*', //否则,多个Line对象的长度都会被绑定到一起。 *ptr = *obj.ptr; }
Line::~Line(void){ cout<< "Freeing memory!"<<endl; delete ptr; }
Line
对象的长度,直接返回指针指向的int
类型数据int Line::getLength(void){ return *ptr; }
display
函数,用于输出Line
对象的长度:void display(Line obj){ cout<< "Length of line : "<<obj.getLength() <<endl; }
对于以下main
函数的内容:
int main(){ Line line1(10); Line line2(line1); //这里调用了拷贝构造函数 display(line1); display(line2); return 0; }
预期的输出是:
Normal constructor allocating ptr. Copy constructor allocating ptr. Length of line : 10 Length of line : 10 Freeing memory! Freeing memory!
但实际输出是:
拷贝构造函数和析构函数被调用了好几次
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!
在设置断点和调试代码之后,发现原因:
Copy constructor allocating ptr. Length of line : 10 Freeing memory!
Freeing memory!
是由于C/C++
的局部变量是存储在栈区stack
的。栈区由编译器自动分配和释放内存。return 0;
的时候,局部变量line1
和line2
被销毁,故析构函数被调用。Freeing memory! --> 对应line2的销毁 Freeing memory! --> 对应line1的销毁