拷贝构造函数与赋值运算符重载

    xiaoxiao2022-07-13  164

    拷贝构造函数

    注意点

    1.类声明只描述如何分配内存,并不会分配内存。因此,不要在类声明中初始化静态成员变量。 特殊情况:静态成员是const或者是枚举型时,则应在类声明中初始化。

    2.会用到复制构造函数的声明: point a(b); point a = b; point a = point b; point *a = new point(b) 中间两个声明是等价的。并且有两种可能性,一种直接使用拷贝构造函数创建对象,一种使用拷贝构造函数创建一个临时变量,再调用重载的赋值运算符。

    3.按值传递和返回对象也将调用拷贝构造函数。

    4.由于第三点原因,我们在写函数参数时,应该使用引用传递对象,可以节省使用拷贝构造函数的时间和创建新对象的空间。

    5.在类对象创建时,要避免浅复制(即使用了默认拷贝构造函数),两个对象指向同一段空间,遇到析构函数时,将会发生同一段空间被释放两次的情况,将会引发报错。

    6.当我们看到类中的数据成员有指针变量或者静态数据成员时,需要主动提供一个显式拷贝构造函数

    常见格式(深复制)

    StringBad::StringBad(const StringBad &st) { num_string++; // 修改静态成员变量,符合我们第6个注意点 len = st.len; // 长度 str = new char[len + 1]; // 分配了一段空间,加1的目的是预留给\0(字符串结束符)空间 strcpy(str, st.str); // 把字符串复制到分配的空间中 }

    赋值运算符重载

    注意点

    1.将一个已有对象赋值给一个对象时,将会使用重载的赋值运算符,在除初始化时,大部分两个对象都有值了。

    2.赋值运算符不会产生新对象,因此不会对静态成员变量产生影响。有人可能会产生疑惑,在初始化时,我们也要用到重载的赋值运算符,那么势必需要修改静态成员变量。其实,初始化,有两种情况,之前已经说明了,细心的小伙伴已经发现了共同点,没错,初始化一定会使用拷贝构造函数,此时已经修改了静态成员变量,不用再担心了。

    3.在重载赋值运算符时,要避免将对象赋值给自身。

    常见格式

    StringBad& StringBad::operator(const StringBad &st) { if(this == &st) // 首先检查自我复制 { return *this } delete[] str // 释放可能有的旧的内容,防止之后产生内存泄漏 len = st.len // 长度 str = new char[len + 1] // 分配一段新空间 strcpy(str, st.str) // 把字符串复制到分配的空间中,此时若刚刚不delete空间,则会产生内存泄漏! }
    最新回复(0)