熟悉c++的朋友都知道,类有两个构造函数,拷贝构造和移动构造。可是,在实际项目中,某些类可能希望禁止复制或移动,例如一个定义资源管理类,或者一个单例模式类。
怎么实现这样一个类呢?这篇文章将实现这样一个模板。方便您可以直接粘贴到你的项目中使用。
我们来定义一个禁止复制的类的模版:
class NonCopyable {
public:
NonCopyable() {}
NonCopyable(NonCopyable &&) {}
NonCopyable &operator=(NonCopyable &&) { return *this; }
private:
NonCopyable(const NonCopyable &) = delete;
NonCopyable& operator=(const NonCopyable &) = delete;
};
我们来测试一下这个基类:
class csdn : NonCopyable {
};
int main() {
csdn c1;
csdn c2(c1);
return 0;
}
g++ -o a -std=c++11 nocopy.cpp 编译一下得到这个结果:
nocopy.cpp: In function \u2018int main()\u2019:
nocopy.cpp:27:15: error: use of deleted function \u2018csdn::csdn(const csdn&)\u2019
27 | csdn c2(c1);
| ^
nocopy.cpp:22:7: note: \u2018csdn::csdn(const csdn&)\u2019 is implicitly deleted because the default definition would be ill-formed:
22 | class csdn : NonCopyable {
| ^~~~
nocopy.cpp:22:7: error: use of deleted function \u2018NonCopyable::NonCopyable(const NonCopyable&)\u2019
nocopy.cpp:8:3: note: declared here
8 | NonCopyable(const NonCopyable &) = delete;
| ^~~~~~~~~~~
报错信息显示拷贝构造函数已经被删除了。无法编译成果。
下面我们来实现一个禁止移动的类:
class NonMovable {
protected:
NonMovable() {}
~NonMovable() {}
private:
NonMovable(NonMovable &&) = delete;
NonMovable& operator=(NonMovable &&) = delete;
};
测试一下:
class csdn : NonMovable {
};
int main() {
csdn c1;
csdn c2 = std::move(c1);
return 0;
}
nomovable.cpp: In function \u2018int main()\u2019:
nomovable.cpp:29:27: error: use of deleted function \u2018csdn::csdn(csdn&&)\u2019
29 | csdn c2 = std::move(c1);
| ^
nomovable.cpp:24:7: note: \u2018csdn::csdn(csdn&&)\u2019 is implicitly deleted because the default definition would be ill-formed:
24 | class csdn : NonMovable {
| ^~~~
nomovable.cpp:24:7: error: use of deleted function \u2018NonMovable::NonMovable(NonMovable&&)\u2019
nomovable.cpp:20:3: note: declared here
20 | NonMovable(NonMovable &&) = delete;
| ^~~~~~~~~~
下面定义一个禁止复制和移动的类:
class NonCopyOrMovable {
protected:
NonCopyOrMovable() {}
~NonCopyOrMovable() {}
private:
NonCopyOrMovable(const NonCopyOrMovable &) = delete;
NonCopyOrMovable(NonCopyOrMovable &&) = delete;
NonCopyOrMovable& operator=(const NonCopyOrMovable &) = delete;
NonCopyOrMovable& operator=(NonCopyOrMovable &&) = delete;
};