ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

[c++]关于拷贝构造函数和析构函数执行次数的思考

2022-08-05 16:00:24  阅读:206  来源: 互联网

标签:Freeing 函数 c++ memory Line 和析构 ptr 构造函数


前言

最近在学习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!

分析

在设置断点和调试代码之后,发现原因:

  • display函数的函数参数是值传递,也就是说在调用时会创建函数参数(Line对象)的副本,并且display函数执行完之后,副本会被删除。
  • 也就是说,每执行一次display函数,都会触发对拷贝构造函数析构函数的调用,就会输出如下的文本:
Copy constructor allocating ptr.
Length of line : 10
Freeing memory!
  • 而输出结尾的两个Freeing memory!是由于C/C++的局部变量是存储在栈区stack的。栈区由编译器自动分配和释放内存。
  • 当程序执行到return 0;的时候,局部变量line1line2被销毁,故析构函数被调用。
  • 并且需要注意的是,这两个输出的顺序是:
Freeing memory!		--> 对应line2的销毁
Freeing memory!		--> 对应line1的销毁
  • 这是因为变量是存储在栈区中的,遵循FILO(First In, Last Out)的顺序。

标签:Freeing,函数,c++,memory,Line,和析构,ptr,构造函数
来源: https://www.cnblogs.com/feixianxing/p/cpp-class-constructor-function.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有