c++11新特性——移动操作

c++11新引入的这个特性实在是太棒了。因为它避免了对象创建过程中的内存分配问题,所以使代码执行的高效率更高。本文讨论对象移动操作的注意事项。

一个c++类要想支持移动操作必须满足如下条件:

  1. move之后的原对象必须处于刚初始化的状态(关于初始化与赋值的概念请查阅《effective c++》对于理解这个条件很重要)。
  2. 销毁移动后的对象必须是安全的(比如:不可出现释放正在使用的资源)

下面代码是一个支持移动操作(移动拷贝、移动赋值)的类A。移动构造函数成员初始化表接管了被移动对象的内存,函数体内将被移动对象设置为初始化状态。

class A {
public:
	A(int a) : m_p(nullptr) {
		m_p = new int(a);
	}

	A(const A &ref) {
		if (this->m_p == nullptr) {
			this->m_p = new int(*ref.m_p);
		} else {
			*m_p = *ref.m_p;
		}
	}

	A(A &&ref) : m_p(ref.m_p) { // 接管被移动对象的成员内存;
		ref.m_p = nullptr; // 销毁移动后的对象必须是安全的;
	}

	A &operator=(const A &ref) {
		if (this != &ref) {
			if (this->m_p == nullptr) {
				this->m_p = new int(*ref.m_p);
			} else {
				*m_p = *ref.m_p;
			}
		}

		return *this;
	}

	A &operator=(A &&ref) {
		if (this != &ref) {
			if (m_p) {
				delete m_p;
				m_p = nullptr;
			}
			this->m_p = ref.m_p;
			ref.m_p = nullptr;
		}

		return *this;
	}

	~A() {
		if (m_p) {
			delete m_p;
			m_p = nullptr;
		}
	}

private:
	int *m_p;
};

int main(int argc, char** argv) 
{
	{
		A a(90);
		A a2 = std::move(a);

		A a3(88);
		a3 = std::move(a2);

		A a4 = a3;
	}

	getchar();
}

总结:

1.对象被移动后就不要在对其进行操作了;  

2.自己定义的copy构造或赋值等操作会不会被编译,取决于你代码中有无使用相关操作。(这就是自己写的copy构造函数等中断点不会命中的原因)

你可能感兴趣的:(c++11,c++,移动构造,c++11)