在C++中,一個(gè)類可以有多個(gè)構(gòu)造函數(shù),這被稱為構(gòu)造函數(shù)的重載。移動(dòng)構(gòu)造函數(shù)是一種特殊的構(gòu)造函數(shù),它接受一個(gè)右值引用參數(shù),并將該參數(shù)的資源移動(dòng)到對象中,而不是復(fù)制資源。這可以提高性能,特別是對于大型對象或資源密集型對象。
要將移動(dòng)構(gòu)造函數(shù)與其他構(gòu)造函數(shù)配合使用,可以使用C++11引入的std::move
模板函數(shù)。std::move
可以將左值轉(zhuǎn)換為右值引用,從而使移動(dòng)構(gòu)造函數(shù)可以與其他構(gòu)造函數(shù)配合使用。
以下是一個(gè)示例,演示了如何將移動(dòng)構(gòu)造函數(shù)與其他構(gòu)造函數(shù)配合使用:
#include <iostream>
#include <string>
#include <utility>
class MyString {
public:
// 默認(rèn)構(gòu)造函數(shù)
MyString() : data(nullptr), size(0) {}
// 參數(shù)化構(gòu)造函數(shù)
MyString(const char* str) {
size = std::strlen(str);
data = new char[size + 1];
std::strcpy(data, str);
}
// 移動(dòng)構(gòu)造函數(shù)
MyString(MyString&& other) noexcept : data(other.data), size(other.size) {
other.data = nullptr;
other.size = 0;
}
// 析構(gòu)函數(shù)
~MyString() {
delete[] data;
}
// 賦值運(yùn)算符
MyString& operator=(const MyString& other) {
if (this != &other) {
char* new_data = new char[other.size + 1];
std::strcpy(new_data, other.data);
delete[] data;
data = new_data;
size = other.size;
}
return *this;
}
// 移動(dòng)賦值運(yùn)算符
MyString& operator=(MyString&& other) noexcept {
if (this != &other) {
delete[] data;
data = other.data;
size = other.size;
other.data = nullptr;
other.size = 0;
}
return *this;
}
// 打印字符串
void print() const {
std::cout << data << std::endl;
}
private:
char* data;
size_t size;
};
int main() {
MyString s1("Hello");
MyString s2 = std::move(s1); // 使用移動(dòng)構(gòu)造函數(shù)
s1.print(); // 輸出空字符串,因?yàn)閟1的資源已被移動(dòng)到s2
s2.print(); // 輸出"Hello"
return 0;
}
在這個(gè)示例中,MyString
類有四個(gè)構(gòu)造函數(shù):默認(rèn)構(gòu)造函數(shù)、參數(shù)化構(gòu)造函數(shù)、移動(dòng)構(gòu)造函數(shù)和賦值運(yùn)算符。默認(rèn)構(gòu)造函數(shù)創(chuàng)建一個(gè)空字符串,參數(shù)化構(gòu)造函數(shù)接受一個(gè)C風(fēng)格字符串并創(chuàng)建一個(gè)新的MyString
對象,移動(dòng)構(gòu)造函數(shù)接受一個(gè)MyString
對象并將其資源移動(dòng)到新對象中,賦值運(yùn)算符將一個(gè)MyString
對象的資源復(fù)制到新對象中。
在main
函數(shù)中,我們首先創(chuàng)建了一個(gè)MyString
對象s1
,然后使用std::move
將其移動(dòng)到另一個(gè)MyString
對象s2
中。注意,移動(dòng)后,s1
的資源已被釋放,因此其打印輸出為空字符串。