文章目录
- C++特殊类设计
- 1、设计一个类,不能被拷贝
- 2、设计一个类,只能在堆上创建对象
- 3、设计一个类,只能在栈上创建对象
- 4、设计一个类,不能被继承
- 5、设计一个类,只能创建一个对象(单例模式)
C++特殊类设计
1、设计一个类,不能被拷贝
拷贝只会放生在两个场景中:拷贝构造函数以及赋值运算符重载,因此想要让一个类禁止拷贝,只需让该类不能调用拷贝构造函数以及赋值运算符重载即可。
C++98中:讲拷贝构造和赋值重载设置为私有,并且只声明不定义。
原因:设置成私有是如果只声明没有设置成private,用户自己如果在类外定义了,就可以不能禁止拷贝了。只声明不定义,不定义是因为该函数根本不会调用,定义了其实也没有什么意义,不写反而还简单,而且如果定义了成员函数内部就可以拷贝了,所以不要定义。
class CopyBan { // ... private: CopyBan(const CopyBan&); CopyBan& operator=(const CopyBan&); //... };
C++11中:默认成员函数使用delete关键字可以禁止编译器生成。
// 设计一个类,不能被拷贝 class CannotCopy { public: CannotCopy(){}; CannotCopy(const CannotCopy &cnp) = delete; CannotCopy &operator=(const CannotCopy &cnp) = delete; }; // 特殊类设计 int main() { CannotCopy cnp1; CannotCopy cnp2(cnp1);// 报错 CannotCopy cnp3 = cnp1;// 报错 CannotCopy cnp4; cnp4 = cnp1;// 报错 return 0; }
2、设计一个类,只能在堆上创建对象
实现方式:
- 将构造函数设置为私有,并且将拷贝构造的声明设置为私有,防止有人调用拷贝构造在栈上生成对象。
- 提供一个静态成员函数,在该静态成员函数完成在堆上创建对象。
class CreateHeap { public: static CreateHeap *Create(int x, int y) { return new CreateHeap(x, y); } void Debug() { cout } CreateHeap(const CreateHeap& cnp) = delete; int _x; int _y; }; int main() { // 不能直接使用构造函数,不然该对象就是栈上的 // CreateHeap ch; CreateHeap *pcn = CreateHeap::Create(3, 7); pcn-Debug(); return 0; } public: static CreateHeap Create(int x, int y) { return CreateHeap(x, y); } void Debug() { cout } CreateHeap(const CreateHeap &cnp) = delete; int _x; int _y; }; int main() { CreateHeap pcn = CreateHeap::Create(3, 7); // CreateHeap* pcn1 = new CreateHeap(pcn);// 报错,拷贝构造没定义 pcn.Debug(); return 0; } public: static CreateHeap Create(int x, int y) { return CreateHeap(x, y); } void Debug() { cout } // CreateHeap(const CreateHeap &cnp) = delete; int _x; int _y; }; int main() { CreateHeap pcn = CreateHeap::Create(3, 7); // CreateHeap *pcn1 = new CreateHeap(pcn);// 报错,new的属性是delete pcn.Debug(); return 0; } private: Base() {} }; class Drive : public Base { }; int main() { // Drive d; // 报错 return 0; } }; //class Derive:public Base{}; // 报错 public: static Singleton *GetInstance() { return &sl; } void Debug() { cout } // 防止通过拷贝来创建新对象 Singleton(const Singleton &sl) = delete; Singleton &operator=(const Singleton &sl) = delete; static Singleton sl; }; Singleton Singleton::sl = {3, 4, new int(10)}; // 在程序入口之前就完成单例对象的初始化 int main() { Singleton *psl = Singleton::GetInstance(); psl-Debug(); Singleton *psl1 = Singleton::GetInstance(); psl1-Debug(); return 0; } public: // 这里涉及到线程安全问题,需要加锁,后面学了线程再补充 static Singleton *GetInstance() { if (!_psl) // 如果_psl为空,就创建对象,否则(已经有对象了)不创建 _psl = new Singleton(3, 4, new int(10)); // _psl = new Singleton; return _psl; } void Debug() { cout if (_psl) { delete _psl; _psl = nullptr; } } private: int _x; int _y; int *_p; Singleton(int x = 1, int y = 2, int *p = nullptr) : _x(x), _y(y), _p(p) {} // 防止通过拷贝来创建新对象 Singleton(const Singleton &sl) = delete; Singleton &operator=(const Singleton &sl) = delete; ~Singleton() { cout public: ~GC() { Singleton::DelInstance(); } }; static GC gc; }; Singleton *Singleton::_psl = nullptr; // 初始化为nullptr,表明当前还没调用过 Singleton::GC Singleton::gc; int main() { Singleton *psl = Singleton::GetInstance(); psl-Debug(); Singleton *psl1 = Singleton::GetInstance(); psl1-Debug(); // psl-DelInstance(); cout