以下是详解C++中对构造函数和赋值运算符的复制和移动操作的完整攻略:
1. 构造函数的复制和移动操作
复制构造函数
当我们定义一个新的对象并且使用已经存在的对象进行初始化时,复制构造函数就会被调用。复制构造函数的定义格式如下:
class MyClass {
public:
MyClass(); // 默认构造函数
MyClass(const MyClass& other); // 复制构造函数
// ...
};
其中,参数为 const MyClass&
类型的 other
是需要被复制构造的对象。下面是一个示例:
class Person {
public:
Person(const std::string& name, int age);
Person(const Person& other); // 复制构造函数
// ...
};
Person alice("Alice", 20);
Person bob = alice; // 调用复制构造函数,bob 会和 alice 的属性一样
这里定义了 Person
类,并且在调用复制构造函数时,bob
会和 alice
的属性一样。由于复制构造函数是需要使用上一个对象进行初始化的,所以我们一般都会将其定义为 const
引用类型。
移动构造函数
在 C++11 的新特性中,移动构造函数被引入。当我们需要将一个右值对象的资源(如内存)交给一个新的对象时,移动构造函数就会被调用。移动构造函数的定义格式如下:
class MyClass {
public:
MyClass(); // 默认构造函数
MyClass(MyClass&& other); // 移动构造函数
// ...
};
其中,参数为 MyClass&&
类型的 other
是需要移动构造的对象。下面是一个示例:
class Array {
public:
Array(int len) {
m_ptr = new int[len];
}
Array(Array&& other) {
m_ptr = other.m_ptr;
other.m_ptr = nullptr;
}
~Array() {
if (m_ptr != nullptr) {
delete[] m_ptr;
}
}
private:
int* m_ptr;
};
Array f() {
Array temp(10);
return temp;
}
int main() {
Array arr = f(); // 调用移动构造函数
return 0;
}
在上面的示例中,我们定义了一个 Array
类并且在 f()
函数中返回一个 Array
对象 temp
。由于 temp
是一个右值对象,因此在调用 arr = f()
的同时会调用 Array
的移动构造函数,将 temp
的资源移动给 arr
。
2. 赋值运算符的复制和移动操作
复制赋值运算符
当我们将一个对象赋值给另一个对象时,复制赋值运算符就会被调用。复制赋值运算符的定义格式如下:
class MyClass {
public:
MyClass(); // 默认构造函数
MyClass& operator=(const MyClass& other); // 复制赋值运算符
// ...
};
其中,参数为 const MyClass&
类型的 other
是需要赋值的对象。下面是一个示例:
class Point {
public:
Point(int x, int y);
Point(const Point& other); // 复制构造函数
Point& operator=(const Point& other); // 复制赋值运算符
// ...
};
Point p1(1, 2);
Point p2(3, 4);
p1 = p2; // 调用赋值运算符,p1 的属性将会和 p2 的一样
在上面的示例中,我们定义了一个 Point
类并且将 p2
赋值给了 p1
。由于这里是赋值操作,所以我们也会将其定义为 const
引用类型。
移动赋值运算符
与移动构造函数类似,移动赋值运算符也被引入到了 C++11 的新特性中。当我们需要将一个右值对象的资源(如内存)交给另一个对象时,移动赋值运算符就会被调用。移动赋值运算符的定义格式如下:
class MyClass {
public:
MyClass(); // 默认构造函数
MyClass& operator=(MyClass&& other); // 移动赋值运算符
// ...
};
其中,参数为 MyClass&&
类型的 other
是需要移动赋值的对象。下面是一个示例:
class Array {
public:
Array(int len) {
m_ptr = new int[len];
}
Array& operator=(Array&& other) {
std::swap(m_ptr, other.m_ptr);
return *this;
}
~Array() {
if (m_ptr != nullptr) {
delete[] m_ptr;
}
}
private:
int* m_ptr;
};
Array f() {
Array temp(10);
return temp;
}
int main() {
Array arr1(5), arr2(10);
arr1 = std::move(arr2); // 调用移动赋值运算符
return 0;
}
在上面的示例中,我们定义了一个 Array
类并且在 f()
函数中返回一个 Array
对象 temp
。在 main()
函数中,我们将一个对象赋值给另一个对象,并且使用了 std::move()
,这样就会调用 Array
的移动赋值运算符,将 arr2
的资源移动给 arr1
。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解C++中对构造函数和赋值运算符的复制和移动操作 - Python技术站