c++拷贝控制(二)

简介: c++拷贝控制(二)

c++拷贝控制(一)https://developer.aliyun.com/article/1437371

定义行为像指针的类

关键特征

  1. 共享数据:实例之间共享相同的数据。
  2. 引用计数:通常通过引用计数来管理共享数据的生命周期。
  3. 自管理资源:类负责管理其指向的资源,如分配和释放内存。


实现策略

  1. 使用智能指针:如 std::shared_ptr,它自动处理引用计数和资源管理。
  2. 手动引用计数:在类内部手动实现引用计数机制。

示例代码

假设我们有一个简单的 SharedString 类,该类使用 std::shared_ptr 来共享字符串数据:

#include <iostream>
#include <string>
#include <memory>

class SharedString {
private:
    std::shared_ptr<std::string> data;

public:
    SharedString(const char* str = "") : data(std::make_shared<std::string>(str)) {}

    // 使用默认的拷贝构造函数、赋值运算符和析构函数
    SharedString(const SharedString&) = default;
    SharedString& operator=(const SharedString&) = default;
    ~SharedString() = default;

    // 获取字符串
    const std::string& get() const {
        return *data;
    }

    // 其他成员函数...
};

int main() {
    SharedString s1("Hello");
    SharedString s2 = s1; // s1 和 s2 共享相同的数据

    std::cout << "s1: " << s1.get() << ", s2: " << s2.get() << std::endl;

    return 0;
}

在这个例子中,SharedString 类的实例 s1 和 s2 共享相同的字符串。通过使用 std::shared_ptr,当最后一个 SharedString 实例被销毁时,字符串数据会被自动释放。

注意事项


  • 当使用共享数据时,需注意线程安全和同步问题。
  • 确保所有的拷贝操作都正确地管理引用计数。
  • 考虑对象的所有权和生命周期,以防止悬挂指针或内存泄漏。

在 C++ 中,交换操作是一个重要的概念,尤其是在实现拷贝赋值运算符和移动构造函数时。正确的交换操作可以提高代码的效率和安全性。

交换操作

交换操作的基本概念

交换操作的目的是交换两个对象的状态。在许多情况下,这比通过传统的拷贝更高效,特别是对于大型对象或资源密集型对象。

实现交换操作

交换操作通常通过定义一个非成员函数 swap 来实现,该函数接受两个同类型对象的引用并交换它们的内部状态。

当然,我可以提供一个更完整的代码示例,展示如何在 C++ 类中实现交换操作。我们将创建一个简单的类 MyClass,该类将包含一些基本的成员变量和一个交换操作的实现。

完整的示例代码

#include <iostream>
#include <utility> // For std::swap (C++11 and later)

class MyClass {
private:
    int* data;
    size_t size;

public:
    // 构造函数
    MyClass(size_t size) : size(size), data(new int[size]) {
        for (size_t i = 0; i < size; ++i) {
            data[i] = i;  // 示例数据初始化
        }
    }

    // 拷贝构造函数
    MyClass(const MyClass& other) : size(other.size), data(new int[other.size]) {
        std::copy(other.data, other.data + size, data);
    }

    // 拷贝赋值运算符
    MyClass& operator=(MyClass other) {
        swap(*this, other);
        return *this;
    }

    // 移动构造函数
    MyClass(MyClass&& other) noexcept : MyClass() {
        swap(*this, other);
    }

    // 移动赋值运算符
    MyClass& operator=(MyClass&& other) noexcept {
        swap(*this, other);
        return *this;
    }

    // 析构函数
    ~MyClass() {
        delete[] data;
    }

    // 交换成员函数
    friend void swap(MyClass& first, MyClass& second) noexcept {
        using std::swap;
        swap(first.size, second.size);
        swap(first.data, second.data);
    }

    // 用于演示的函数
    void print() const {
        for (size_t i = 0; i < size; ++i) {
            std::cout << data[i] << ' ';
        }
        std::cout << std::endl;
    }
};

int main() {
    MyClass obj1(5);
    MyClass obj2(10);

    std::cout << "Original obj1: ";
    obj1.print();

    std::cout << "Original obj2: ";
    obj2.print();

    // 使用交换操作
    swap(obj1, obj2);

    std::cout << "Swapped obj1: ";
    obj1.print();

    std::cout << "Swapped obj2: ";
    obj2.print();

    return 0;
}
Original obj1: 0 1 2 3 4
Original obj2: 0 1 2 3 4 5 6 7 8 9
Swapped obj1: 0 1 2 3 4 5 6 7 8 9
Swapped obj2: 0 1 2 3 4

代码说明


这个 MyClass 类包含一个动态分配的整型数组和一个表示数组大小的成员变量。


实现了构造函数、拷贝构造函数、拷贝赋值运算符、移动构造函数、移动赋值运算符和析构函数。


实现了一个 swap 函数,用于交换两个 MyClass 实例的内部状态。


在 main 函数中,创建了两个 MyClass 对象,并使用 swap 函数展示了交换操作的效果。


obj1 最初包含 5 个元素(从 0 到 4)。


obj2 最初包含 10 个元素(从 0 到 9)。


执行交换后,obj1 和 obj2 的内容互换。

目录
相关文章
|
6月前
|
Linux 编译器 C++
C/C++性能优化:从根本上消除拷贝操作的浪费
C/C++性能优化:从根本上消除拷贝操作的浪费
865 1
|
6月前
|
Linux 数据处理 C++
Linux系统编程 C/C++ 以及Qt 中的零拷贝技术: 从底层原理到高级应用(一)
Linux系统编程 C/C++ 以及Qt 中的零拷贝技术: 从底层原理到高级应用
270 0
|
6月前
|
存储 Linux API
Linux系统编程 C/C++ 以及Qt 中的零拷贝技术: 从底层原理到高级应用(三)
Linux系统编程 C/C++ 以及Qt 中的零拷贝技术: 从底层原理到高级应用
125 1
|
6月前
|
消息中间件 Linux 数据处理
Linux系统编程 C/C++ 以及Qt 中的零拷贝技术: 从底层原理到高级应用(二)
Linux系统编程 C/C++ 以及Qt 中的零拷贝技术: 从底层原理到高级应用
195 1
|
1月前
|
安全 编译器 程序员
【C++篇】C++类与对象深度解析(六):全面剖析拷贝省略、RVO、NRVO优化策略
【C++篇】C++类与对象深度解析(六):全面剖析拷贝省略、RVO、NRVO优化策略
46 2
|
4月前
|
机器学习/深度学习 算法 搜索推荐
|
5月前
|
算法 搜索推荐 C++
C++之STL常用算法(遍历、查找、排序、拷贝、替换、算数生成、集合)
C++之STL常用算法(遍历、查找、排序、拷贝、替换、算数生成、集合)
|
6月前
|
算法 C++ 容器
黑马c++ STL常用算法 笔记(4) 常用拷贝和替换算法
黑马c++ STL常用算法 笔记(4) 常用拷贝和替换算法
|
5月前
|
编译器 C++ 容器
【C++进阶】深入STL之vector:深入研究迭代器失效及拷贝问题
【C++进阶】深入STL之vector:深入研究迭代器失效及拷贝问题
163 0
|
6月前
|
编译器 C++ Windows
【C++】vector问题解决(非法的间接寻址,迭代器失效 , memcpy拷贝问题)
不使用memcpy函数不就可以了,然后我们使用简单粗暴的赋值拷贝,这样就不会发生浅拷贝问题了!!!
128 1