C++中的拷贝控制操作

简介: C++中的拷贝控制操作

31.jpg

1.拷贝构造函数 vs 赋值运算符重载


      当我们定义一个类时,会显式或隐式地指定了此类的对象在拷贝、赋值和销毁时做什么。一个类通过定义三种特殊的成员函数来控制这些操作,分别是拷贝构造函数、赋值运算符和析构函数。拷贝控制操作:拷贝构造函数被用来以同类型对象初始化自我对象,赋值运算符重载被用来从另一个同类型对象中拷贝其值到自我对象中析构函数定义了此类型的对象销毁时做什么。


注意:如果一个新对象被定义,一定会有个构造函数被调用,不可能调用赋值运算符重载如果没有新的对象被定义,就不会有构造函数被调用,那么就会调用赋值运算符重载


2.三/五法则

由于拷贝控制操作是由三个特殊的成员函数来完成的,所以称此为“C++三法则”。在较新的C++11标准中,为了支持移动语义,又增加了移动构造函数和移动赋值运算符,这样共有五个特殊的成员函数,所以又称为“C++五法则”。也就是说,“三法则”是针对较旧的C++89标准说的,“五法则”是针对较新的C++11标准说的。为了统一称呼,人们把它称为“C++ 三/五法则”。


3.实例演示


1#include <iostream>
  2#include <cstdlib>
  3#include <cstring>
  4
  5using namespace std;
  6
  7
  8class Array
  9{
 10public:
 11    Array(int len);
 12    Array(const Array &arr); // 拷贝构造函数
 13    ~Array();
 14
 15public:
 16    int operator[](int i) const { return m_p[i]; } // 以常成员函数(只读)形式重载[]运算符
 17    int &operator[](int i) { return m_p[i]; }      // 获取元素(写入)
 18    Array &operator=(const Array &arr);            // 重载赋值运算符!!!operator=()的形参类型是const Array &,这样不但能够避免在传参时调用拷贝构造函数,还能够同时接收const类型和非const类型的实参
 19    int length() const { return m_len; }
 20    void show();
 21
 22private:
 23    int m_len;
 24    int *m_p;
 25};
 26
 27// 构造函数的定义
 28Array::Array(int len) : m_len(len)
 29{
 30    m_p = (int *)calloc(len, sizeof(int)); // 动态分配内存空间,使得指针m_p指向新分配的内存空间
 31}
 32// 拷贝构造函数的定义
 33Array::Array(const Array &arr)
 34{
 35    this->m_len = arr.m_len;
 36    this->m_p = (int *)calloc(this->m_len, sizeof(int));
 37    memcpy(this->m_p, arr.m_p, m_len * sizeof(int));
 38}
 39
 40Array::~Array()
 41{
 42    free(m_p);
 43}
 44// 重载赋值运算符
 45Array &Array::operator=(const Array &arr)
 46{ // operator=()的返回值类型是Array &,这样不但能够避免在返回数据时调用拷贝构造函数,还能够达到连续赋值的目的
 47    if (this != &arr)
 48    { // 判断是否是给同一个对象赋值
 49        this->m_len = arr.m_len;
 50        free(this->m_p);
 51        this->m_p = (int *)calloc(this->m_len, sizeof(int));
 52        memcpy(this->m_p, arr.m_p, m_len * sizeof(int));
 53    }
 54    return *this; // 表示返回当前对象
 55}
 56
 57// 普通成员函数的定义
 58void Array::show()
 59{
 60    cout << "我是普通成员函数....\n";
 61}
 62
 63// 打印数组元素
 64void printArray(const Array &arr)
 65{
 66    int len = arr.length();
 67    for (int i = 0; i < len; i++)
 68    {
 69        if (i == len - 1)
 70        {
 71            cout << arr[i] << endl;
 72        }
 73        else
 74        {
 75            cout << arr[i] << ", ";
 76        }
 77    }
 78}
 79
 80int main()
 81{
 82    Array arr1(10);
 83    for (int i = 0; i < 10; i++)
 84    {
 85        arr1[i] = i;
 86    }
 87    cout << "arr1:";
 88    printArray(arr1);
 89
 90    Array arr2(5);
 91    for (int i = 0; i < 5; i++)
 92    {
 93        arr2[i] = i;
 94    }
 95    cout << "arr2:";
 96    printArray(arr2);
 97    cout << "------------------------------------\n";
 98    arr2 = arr1; // 调用operator=()
 99    cout << "将arr1赋值给arr2:";
100    printArray(arr2);
101    arr2[3] = 234; // 修改arr2的数据不会影响arr1,如果把operator=()注释掉,修改arr2的值就会影响arr1的值
102    arr2[7] = 920;
103    cout << "修改arr2的值不会影响arr1:";
104    printArray(arr1);
105    return 0;
106}


32.png


4.参考资料


[1] https://www.cnblogs.com/yongdaimi/p/7121151.html



相关文章
|
2月前
|
Linux 编译器 C++
C/C++性能优化:从根本上消除拷贝操作的浪费
C/C++性能优化:从根本上消除拷贝操作的浪费
56 0
|
2月前
|
Linux 数据处理 C++
Linux系统编程 C/C++ 以及Qt 中的零拷贝技术: 从底层原理到高级应用(一)
Linux系统编程 C/C++ 以及Qt 中的零拷贝技术: 从底层原理到高级应用
80 0
|
2月前
|
存储 Linux API
Linux系统编程 C/C++ 以及Qt 中的零拷贝技术: 从底层原理到高级应用(三)
Linux系统编程 C/C++ 以及Qt 中的零拷贝技术: 从底层原理到高级应用
32 1
|
2月前
|
消息中间件 Linux 数据处理
Linux系统编程 C/C++ 以及Qt 中的零拷贝技术: 从底层原理到高级应用(二)
Linux系统编程 C/C++ 以及Qt 中的零拷贝技术: 从底层原理到高级应用
34 1
|
23天前
|
人工智能 机器人 C++
【C++/Python】Windows用Swig实现C++调用Python(史上最简单详细,80岁看了都会操作)
【C++/Python】Windows用Swig实现C++调用Python(史上最简单详细,80岁看了都会操作)
|
2月前
|
存储 JSON 安全
【C++ JSON库 json值的创建手段】深入探究C++中JSON对象定位与操作:从引用到回调函数
【C++ JSON库 json值的创建手段】深入探究C++中JSON对象定位与操作:从引用到回调函数
67 0
|
15天前
|
存储 C++
二叉树的操作(C++实现)
二叉树的操作(C++实现)
|
15天前
|
C++
有序链表的操作(底层c++实现)
有序链表的操作(底层c++实现)
|
20天前
|
C++ 索引
C++ 获取数组大小、多维数组操作详解
本文介绍了如何获取数组的大小和使用`sizeof()`运算符。`sizeof()`返回数组所占字节数,而非元素个数。要获取元素个数,需除以单个元素的大小。此外,文章展示了如何使用`sizeof()`遍历数组,包括多维数组。多维数组是数组的数组,可用来表示网格。文中以战舰游戏为例说明了多维数组的应用。最后提到了微信公众号`Let us Coding`以获取更多内容。
22 0
|
28天前
|
NoSQL C++
c++中包含string成员的结构体拷贝导致的double free问题
c++中包含string成员的结构体拷贝导致的double free问题
9 0