C++函数返回局部变量/拷贝构造/移动构造/拷贝赋值/移动赋值*

#include <iostream>
using namespace std;
int g_base_num = 1;

class Teacher {
   public:
    int id;
    int* studentIds{nullptr};
    int count;

   public:
    // 构造函数
    Teacher(int id, int count) {
        this->id = id;
        this->count = count;
        this->studentIds = new int[count];
        for (int i = 0; i < count; i++) {
            this->studentIds[i] = (i + 1) * g_base_num;
        }
        g_base_num *= 10;
        cout << "contrustor" << endl;
    }

    // 拷贝构造函数:尽量使用深拷贝
    Teacher(const Teacher& other) {
        this->id = id;
        this->count = other.count;
        this->studentIds = new int[count];
        for (int i = 0; i < count; i++) {
            /* code */
            this->studentIds[i] = other.studentIds[i];
        }
        cout << "copy constructor" << endl;
    }

    //移动构造函数
    Teacher(Teacher&& other) {
        this->id = other.id;
        this->count = other.count;
        this->studentIds = other.studentIds;
        other.studentIds = nullptr;
        cout << "move constructor" << endl;
    }

    // 移动赋值
    Teacher& operator=(Teacher&& ch) {
        cout << "yi dong fu zhi yun suan fu" << endl;

        // 释放this中动态分配的内存
        delete this->studentIds;

        this->id = ch.id;
        this->count = ch.count;
        this->studentIds = ch.studentIds;  // 转移动态内存到this
        ch.studentIds = nullptr;
    }

    // 拷贝赋值
    Teacher& operator=(Teacher& ch) {
        cout << "copy fu zhi yun suan fu" << endl;

        // 释放this中动态分配的内存
        delete this->studentIds;

        // 深拷贝
        this->studentIds = new int[ch.count];
        for (int i = 0; i < ch.count; i++) {
            this->studentIds[i] = ch.studentIds[i];
        }

        this->id = ch.id;
        this->count = ch.count;
    }

    ~Teacher() {
        if (this->studentIds) {
            delete this->studentIds;
            this->studentIds = nullptr;
        }
    }
};

Teacher GetTeacher() {  // 借助了移动copy构造函数的能力,相当于返回了局部变量
    Teacher t(1, 4);
    for (int i = 0; i < t.count; i++) {
        t.studentIds[i] = i;
    }
    cout << "begin to return" << endl;
    return t;
}

void PrintTeacher(Teacher&& ch) { cout << endl; }

int main(int argc, char const* argv[]) {
    // 这是一个临时变量(右值)构造左值的情况,所以这里的赋值操作会调用移动够早函数
    cout << "=============begin to get one obj=============" << endl;
    // 在C++中返回对象的时候,对象需要经过2次拷贝构造函数的调用才能够完成返回对象的传递。一次拷贝到栈上的临时对象里,另一次把临时
    // 对象拷贝到存储返回值的对象里
    Teacher p = GetTeacher();
    for (int i = 0; i < p.count; i++) {
        cout << p.studentIds[i] << " ";
    }
    cout << endl;
    cout << "=============end get one obj=============" << endl;
    cout << endl;

    cout << "=============begin to copy constructor=============" << endl;
    // 拷贝构造函数要使用深拷贝
    Teacher tt(p);
    cout << "=============end copy constructor=============" << endl;
    for (int i = 0; i < tt.count; i++) {
        cout << tt.studentIds[i] << " ";
    }
    cout << endl;

    cout << "=============begin to move= function=============" << endl;
    // 使用移动构造函数,经过移动后,p本身的地址并没有发生变化
    p = Teacher(1, 2);
    for (int i = 0; i < p.count; i++) {
        cout << p.studentIds[i] << " ";
    }
    cout << endl;
    cout << "=============end move= function=============" << endl;

    cout << endl;

    cout << "=============begin to copy= function=============" << endl;
    p = tt;
    for (int i = 0; i < p.count; i++) {
        cout << p.studentIds[i] << " ";
    }
    cout << endl;
    cout << "=============end copy= function=============" << endl;
    cout << endl;

    cout << "end main" << endl;
    return 0;
}
posted @ 2021-10-29 21:20  邱明成  阅读(366)  评论(0编辑  收藏  举报