class MoveConClass {
public:
MoveConClass(){}
~MoveConClass() {
if (str) {
delete[] str;
str = nullptr;
}
}
MoveConClass(const char* t) {
if (t) {
int count = strlen(t)+1;
str = new char[count];
strcpy_s(str, count, t);
}
}
// 拷贝函数,一般需要处理深度拷贝
MoveConClass(const MoveConClass& a) {
k = a.k;
if (a.str) {
int c = strlen(a.str) + 1;
str = new char[c];
strcpy_s(str, c, str);
}
test_int = a.test_int;
std::cout << "MoveConClass(const MoveConClass& a)" << k << std::endl;
}
// 移动构造,浅拷贝,并且右值指针置空,避免右值释构时释放该内存
MoveConClass(MoveConClass&& a) noexcept: str(a.str){
a.str = nullptr;
k = a.k;
test_int = std::move(a.test_int);
std::cout << "MoveConClass(MoveConClass&& a)" << k<< ", "<< str << std::endl;
}
int k = 0;
char* str = nullptr;
std::vector<int> test_int;
};
实现移动构造实现后,我们就可以利用该特性,处理一些数据快速拷贝,例如我们处理对该对象operator+的处理
static MoveConClass operator+(const MoveConClass& a, const MoveConClass& b) {
MoveConClass d;
int a_count = strlen(a.str);
int count = a_count + strlen(b.str) +1;
d.str = new char[count];
strcpy_s(d.str, count, a.str);
strcpy_s(d.str + a_count, count - a_count, b.str);
d.test_int.insert(d.test_int.end(), a.test_int.begin(), a.test_int.end());
d.test_int.insert(d.test_int.end(), b.test_int.begin(), b.test_int.end());
return d;
}
实际使用时可以写如下代码
MoveConClass a("this is ");
a.test_int = { 12,12,12,1,24,233 };
MoveConClass b("a test");
b.test_int = { 34,34, 5, 6, 1213 };
MoveConClass c = a + b;
实现方式类似于强转: static_cast<T&&>(value)
实现方式类似于在对应类型上进行&&操作,如果T是左值,则是&&转化后,变右值,如果是T是右值,“右值的右值会变左值”。
template <typename T>
static void test_copy(T&& a) {
std::cout << "inside test copy!!" << std::endl;
MoveConClass b = std::forward<T>(a);
std::cout << "the b is :s" << b;
}
纯个人理解,欢迎批评
// 一般避免数据拷贝的方法
A a;// 先创建A
create_a_data(&a); // 传入指针或引用
// 使移动构造后, 可以这样写
A a = create_a_data();
因篇幅问题不能全部显示,请点此查看更多更全内容