c++ 拷贝构造函数学习

2021/5/23 22:25:49

本文主要是介绍c++ 拷贝构造函数学习,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

拷贝构造函数

关于拷贝构造函数,初学的我第一印象是在用一个对象去初始化另一个对象时,会调用拷贝构造函数。其实,以下三种情况,拷贝构造函数会被调用
1)用类的对象去初始化另一个对象时;
2)函数的形参是类的对象,在调用函数时 进行形参和实参的结合;
3)函数的返回值是类的对象时,在函数执行完返回调用者时。
对于第一点,很好理解,这里不赘述;
对第二点,回顾函数的调用方式 出现在函数定义中的参数称为形参,出现在函数调用中的参数为形参形参在函数定义时,编译器并不为其分配存储空间,只有在函数调用时,临时为形参分配空间,接收来自实参的值。函数调用结束后,该内存空间被释放
看下面例子1:

#include <iostream>
using namespace std;

class point{
private:
    int x;
    int y;
public:
    point()
    {
        cout<<"construct"<<endl;
    }
    point(const point &p)
    {
        cout<<"copy construct"<<endl;

    }
    int get_x()
    {
        return x;
    }

    ~point()
    {
        cout<<"destruct"<<endl;
    }

};

void f1(point p)
{
    cout<<p.get_x()<<endl;
}
point f2(){
    return point();
}
int main() {
    point p1;
    f1(p1);
    return 0;
}

关闭返回值优化后,结果如下:
在这里插入图片描述
可以看到,在关闭返回值优化后,在执行f1(p1) 时,调用了拷贝构造函数。原因在于,p1对象作为实参,传递给f1()函数的形参p 时, 编译器会为这个形参p临时分配存储空间,也就是临时对象,用以存放实参p1。f1()函数调用结束后,该临时对象被析构。

对于第三点,看下面例子

#include <iostream>
using namespace std;

class point{
private:
    int x;
    int y;
public:
    point()
    {
        cout<<"construct"<<endl;
    }
    point(const point &p)
    {
        cout<<"copy construct"<<endl;

    }
    int get_x()
    {
        return x;
    }

    ~point()
    {
        cout<<"destruct"<<endl;
    }

};

void f1(point p)
{
    cout<<p.get_x()<<endl;
}
point f2(){
    return point();
}
int main() {
    point p1 = f2();
    return 0;
}

在这里插入图片描述
对于上面6条输出,解释如下:
1—construt :执行f2() 里面的 point(),进行构造;
2—copy construct :在执行 return point () 语句时,会调用拷贝构造函数 复制 point()的一个临时对象;
3—destruct:销毁上面产生的一个临时对象
4—copy construct:在执行main() 函数中赋值语句,亦会产生一个临时对象,调用拷贝构造函数;
5— destruct:析构4中的临时对象;
6—destruct:析构p1;

可以看到,关于临时对象的问题会影响对象初始化的效率,特别是对于包含大量成员数据的类多次深拷贝;关于拷贝构造函数的三点情况分析,主要目的是为了进一步学习后面的右值引用即移动语句来处理这类问题。

浅拷贝/深拷贝

上面提到了深拷贝,其实关于浅拷贝和深拷贝是关于怎么处理值和指针的问题。
浅拷贝就是拷贝一个类中的所有成员变量的值,也包括指针的值。
深拷贝除了拷贝所有成员变量的值,同时也把指针指向的数据也拷贝过来了;

这样做的原因不难想象, 假如单纯的只使用浅拷贝,例如b是由a拷贝过来的,里面都包含指针成员变量。那么a和b中的指针实际上是指向同一地址单元的,假如我此时释放了a中的指针所指的单元,那么会使得b中的指针称为野指针,易发生内存泄漏。类默认是浅拷贝,对于含有指针变量的类而言,一般采用深拷贝,需要重写拷贝构造函数。



这篇关于c++ 拷贝构造函数学习的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程