第二天的课根本跟不上啊 难难难啊

编程实现三个数求最大

编程实现求解一元二次方程

传参问题

直接使用返回值

复制控制

复制控制是指在C++中控制对象复制行为的机制,

包括拷贝构造函数(copy constructor)、

赋值操作符(copy assignment operator)、

移动构造函数(move constructor)

和移动赋值操作符(move assignment operator)。

通过这些函数,可以控制对象在复制、赋值和移动时的具体行为,

确保资源的正确管理和高效操作。

### 复制控制函数的种类

1. **拷贝构造函数**:
   - 当创建一个对象作为另一个对象的副本时,调用拷贝构造函数。
   - 语法:`ClassName(const ClassName &other);`

2. **赋值操作符**:
   - 当一个已存在的对象被赋值为另一个对象时,调用赋值操作符。
   - 语法:`ClassName& operator=(const ClassName &other);`

3. **移动构造函数**:
   - 当一个对象被移动构造到另一个对象时(通常是从一个临时对象),调用移动构造函数。
   - 语法:`ClassName(ClassName &&other) noexcept;`

4. **移动赋值操作符**:
   - 当一个已存在的对象被移动赋值为另一个对象时,调用移动赋值操作符。
   - 语法:`ClassName& operator=(ClassName &&other) noexcept;`

### 具体示例

让我们创建一个简单的类 `MyClass` 来展示这些复制控制函数:

```cpp
#include <iostream>
#include <cstring>

class MyClass {
private:
    char* data;

public:
    // 默认构造函数
    MyClass() : data(nullptr) {
        std::cout << "默认构造函数" << std::endl;
    }

    // 带参数的构造函数
    MyClass(const char* str) {
        std::cout << "带参数的构造函数" << std::endl;
        data = new char[strlen(str) + 1];
        strcpy(data, str);
    }

    // 拷贝构造函数
    MyClass(const MyClass &other) {
        std::cout << "拷贝构造函数" << std::endl;
        data = new char[strlen(other.data) + 1];
        strcpy(data, other.data);
    }

    // 赋值操作符
    MyClass& operator=(const MyClass &other) {
        std::cout << "赋值操作符" << std::endl;
        if (this == &other) return *this; // 防止自赋值
        delete[] data;
        data = new char[strlen(other.data) + 1];
        strcpy(data, other.data);
        return *this;
    }

    // 移动构造函数
    MyClass(MyClass &&other) noexcept {
        std::cout << "移动构造函数" << std::endl;
        data = other.data;
        other.data = nullptr; // 防止原对象释放资源
    }

    // 移动赋值操作符
    MyClass& operator=(MyClass &&other) noexcept {
        std::cout << "移动赋值操作符" << std::endl;
        if (this == &other) return *this; // 防止自赋值
        delete[] data;
        data = other.data;
        other.data = nullptr; // 防止原对象释放资源
        return *this;
    }

    // 析构函数
    ~MyClass() {
        std::cout << "析构函数" << std::endl;
        delete[] data;
    }

    // 打印数据
    void print() const {
        if (data) {
            std::cout << "数据: " << data << std::endl;
        } else {
            std::cout << "数据为空" << std::endl;
        }
    }
};

int main() {
    MyClass obj1("Hello");
    MyClass obj2 = obj1; // 拷贝构造
    MyClass obj3;
    obj3 = obj1; // 赋值操作

    MyClass obj4 = MyClass("World"); // 移动构造
    MyClass obj5;
    obj5 = MyClass("Move"); // 移动赋值

    obj1.print();
    obj2.print();
    obj3.print();
    obj4.print();
    obj5.print();

    return 0;
}
```

### 解释和如何使用

1. **拷贝构造函数**:
   - 在 `MyClass obj2 = obj1;` 语句中调用。创建一个新对象 `obj2`,并用 `obj1` 的数据初始化它。
   - 拷贝构造函数确保对象 `obj2` 获得自己的资源副本。

2. **赋值操作符**:
   - 在 `obj3 = obj1;` 语句中调用。将现有对象 `obj3` 的数据替换为 `obj1` 的数据。
   - 赋值操作符需要处理自赋值情况(`if (this == &other) return *this;`),并在赋值前释放现有的资源(`delete[] data;`)。

3. **移动构造函数**:
   - 在 `MyClass obj4 = MyClass("World");` 语句中调用。将临时对象的资源移动到 `obj4`,而不是复制。
   - 移动构造函数将临时对象的资源转移到新对象,并将临时对象的资源指针置为空,防止资源被释放两次。

4. **移动赋值操作符**:
   - 在 `obj5 = MyClass("Move");` 语句中调用。将临时对象的资源移动到 `obj5`,而不是复制。
   - 移动赋值操作符类似于移动构造函数,但需要释放现有对象的资源,并处理自赋值情况。

### 总结

- **复制控制**使得我们可以精确控制对象在复制、赋值和移动时的行为,确保资源正确管理和高效操作。
- **拷贝构造函数**和**赋值操作符**用于复制对象,确保每个对象都有自己的资源副本。
- **移动构造函数**和**移动赋值操作符**用于移动对象,转移资源所有权以避免不必要的复制,提高性能。
- 使用这些函数时,需要特别注意资源管理,防止内存泄漏和资源重复释放。

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东东要拼命

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值