c++拷贝控制(一)https://developer.aliyun.com/article/1437371
定义行为像指针的类
关键特征
- 共享数据:实例之间共享相同的数据。
- 引用计数:通常通过引用计数来管理共享数据的生命周期。
- 自管理资源:类负责管理其指向的资源,如分配和释放内存。
实现策略
- 使用智能指针:如 std::shared_ptr,它自动处理引用计数和资源管理。
- 手动引用计数:在类内部手动实现引用计数机制。
示例代码
假设我们有一个简单的 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 的内容互换。