#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
// 隐式的移动构造和移动赋值函数
class A {
int *p;
public:
A(int value) : p(new int(value)) {}
~A() {
std::cout << "delete pointer:" << (void *)p << std::endl;
//查看析够函数删除了哪个指针
delete p;
}
};
// 显式声明移动构造和移动赋值函数
class B {
int *p;
public:
B(int value) : p(new int(value)) {}
~B() {
std::cout << "delete B pointer:" << (void *)p << std::endl;
//查看析够函数删除了哪个指针
delete p;
}
// 注意:移动构造和移动赋值 不像拷贝构造和普通的赋值
// 它的参数是没有const的,因为要把参数的也就是 右值的内容给改掉
// 否则就会有double free的情况
B(B &&a) : p(a.p) { a.p = nullptr; }
B &operator=(B &&a) {
p = a.p;
a.p = nullptr;
return *this;
}
};
int main() {
A a(1);
A b(2);
// std::swap(a, b);
/*首先我们来了解一下std::swap的一些特性
1.大概全貌如下:
template<class T>
void swap(T & a ,T & b);
2.要求T必须满足MoveAssignable和MoveConstructible
通俗讲就是有移动构造函数和移动赋值函数
*/
B a1(1);
B b1(2);
std::swap(a1, b1);
}
/*
*
* 你们会发现一二条发生了重复删除了两次,对于这种小范围new的来说,运行期间并没有报错,但到了大范围new数组和delete数组的时候,就会出现double free的现象。
没错,这是系统自动声明会带来的一些后果,如果你们在类里面new一个对象,我们要显示声明移动构造函数或者把移动构造函数删除掉。
结果如下:
delete pointer:0x558527e3be70
delete pointer:0x558527e3be70
delete pointer:0x558527e3be90
也有可能直接assert就会报错 debug_heap.cpp
*/