特殊类的设计
设计一个不能被拷贝的类
拷贝只会放生在两个场景中:拷贝构造函数以及赋值运算符重载,因此想要让一个类禁止拷贝, 只需让该类不能调用拷贝构造函数以及赋值运算符重载即可。
C++98
将拷贝构造函数与赋值运算符重载只声明不定义,并且将其访问权限设置为私有即可。
class CopyBan { // ... private: CopyBan(const CopyBan&); CopyBan& operator=(const CopyBan&); //... };
设置成私有:如果只声明没有设置成private,用户自己如果在类外定义了,就可以不 能禁止拷贝了 只声明不定义:不定义是因为该函数根本不会调用,定义了其实也没有什么意义,不写 反而还简单,而且如果定义了就不会防止成员函数内部拷贝了。
C++11
C++11扩展delete的用法,delete除了释放new申请的资源外,如果在默认成员函数后跟上 =delete,表示让编译器删除掉该默认成员函数。
class CopyBan { // ... CopyBan(const CopyBan&)=delete; CopyBan& operator=(const CopyBan&)=delete; //... };
设计一个只能在堆创造对象的类
#include <iostream> class HeapOnly { public: static HeapOnly* CreatObj()//然后再写一个函数用于创建堆上的对象 { return new HeapOnly; } //要加上静态!如果没有静态我们就必须先创建对象然后才能调用函数! //但是我们又智能允许才堆上创建对象!必须构造私有化! //有了静态后我们就可以直接用类调用函数了· private: HeapOnly()//首先构造函数私有化 {} //拷贝构造也要私有 HeapOnly(const HeapOnly& hp) = delete; }; int main() { //我们首先要封了构造函数! //不然我们可以随意的在栈/堆/静态区上创建对象! //HeapOnly hp1; //HeapOnly* hp2 = new HeapOnly; //static HeapOnly hp3; HeapOnly* hp4 = HeapOnly::CreatObj(); //如果不私有化拷贝构造 //就可以怎么写 //HeapOnly hp5(*hp4); return 0; }
实现方式:
将类的构造函数私有,拷贝构造声明成私有。防止别人调用拷贝在栈上生成对象。
提供一个静态的成员函数,在该静态成员函数中完成堆对象的创建
另一种思路就是封掉析构函数!这样子出了作用域之后就没有办法调用析构函数了!
但是这时候就没法delete了!我们只能在类里面写一个函数用来释放!
#include <iostream> class HeapOnly { public: void destroyObj() { this->~HeapOnly();//要加上this不然会报错! } private: ~HeapOnly()//首先析构私有化 {} HeapOnly(const HeapOnly& hp) = delete; }; int main() { HeapOnly* hp = new HeapOnly; hp->destroyObj(); return 0; }
设计一个只能在栈上创建的类
class StackOnly { public: static StackOnly CreatObj() { return StackOnly(); } void print() { cout << "hello"; } //void* operator new(size_t) = delete; //void operator delete(void*) = delete; //可以禁掉new和delete! //但是只能禁掉new出来的对象!无法禁掉static创建的对象! private: StackOnly()//构造函数私有化 {} //拷贝构造不用私有化,因为栈上的对象不会调用拷贝构造 }; int main() { StackOnly st = StackOnly::CreatObj(); //StackOnly* st2 = new StackOnly; //static Static so2;//只有封掉构造函数才能将静态区的封掉 //但是这个类是封不死的! //如果不封掉拷贝构造那么下面这种也就没法封死!而且会导致st也无法创建! static StackOnly st1 = StackOnly::CreatObj(); //如果封掉了拷贝构造我们只能怎么使用 StackOnly::CreatObj().print(); //我们不去直接的接收对象! //或者直接使用引用接收 const StackOnly& so4 = CreatObj(); return 0; }
设计一个无法被继承的类
- C++98
//构造私有化 class NonInherit { public: static NonInherit GetInstance() { return NonInherit(); } private: NonInherit() {} };
- C++11
final关键字,final修饰类,表示该类不能被继承。
class A final { // .... };