類,不能被拷貝
拷貝只會放生在兩個場景中:拷貝構造函數以及賦值運算符重載,因此想要讓一個類禁止拷貝。
- c++98
將拷貝構造函數與賦值云懸浮重載只聲明不定義,并且將其訪問權限設置為私有
class CopyBan{// ...private:CopyBan(const CopyBan&);CopyBan& operator=(const CopyBan&);//...};
原因:
1.設置為私有:如果只聲明沒有設置成private,用戶自己如果在類外定義了,就不能禁止拷貝了
2.只聲明不定義:不定義是y8inwei該函數根本不會調用,定義了也沒有意義,不寫反而更簡單,如果定義了就不會防止成員函數內部拷貝了
- c++11
c++11擴展delete的用法,delete除了釋放new申請的資源外,如果在默認成員函數后跟上delete,表示讓編譯器刪掉該默認成員函數
class CopyBan{// ...CopyBan(const CopyBan&)=delete;CopyBan& operator=(const CopyBan&)=delete;//...};
類,只能在堆上創建對象
實現方式:
1.將類的構造函數私有,拷貝構造函數私有。防止別人調用拷貝在棧上生成對象
2.提供一個靜態的成員函數,在該靜態成員函數中完成堆對象的創建
一種是析構私有,提供函數析構,一種是構造私有,提供函數返回創建對象
class HeapOnly
{
public:
static HeapOnly* CreateObject() {
return new HeapOnly; }private:
HeapOnly() {}// C++98// 1.只聲明,不實現。因為實現可能會很麻煩,而你本身不需要
// 2.聲明成私有
HeapOnly(const HeapOnly&);
// or// C++11
HeapOnly(const HeapOnly&) = delete;};
類,只能在棧上創建對象
將構造函數私有化,設計靜態方法返回,同時防止拷貝構造,返回對象需要用拷貝,將new重載禁掉
class StackOnly{public:static StackOnly CreateObj(){return StackOnly();}// 禁掉operator new可以把下面用new 調用拷貝構造申請對象給禁掉
// StackOnly obj = StackOnly::CreateObj();// StackOnly* ptr3 = new StackOnly(obj);void* operator new(size_t size) = delete;void operator delete(void* p) = delete;private:StackOnly()
:_a(0){}private:int _a;};
類,不能被繼承
c++98方式
// C++98中構造函數私有化,派生類中調不到基類的構造函數。則無法繼承
class NonInherit{public:static NonInherit GetInstance(){return NonInherit();}private:NonInherit(){}};
c++11方法:
關鍵字final,類不能被繼承
class A final{// ....};
類,只能創建一個對象(單例模式)
設計模式(Desgin Pattern)是一套被反復使用、多數人知曉的、經過分類的、代碼設計經驗的總結。為什么會產生設計模式這樣的東西?就像人類歷史經過一次次打仗總結的套路,研究了《孫子兵法》
使用設計模式的目的:為了代碼可重用性、讓代碼更容易被他人理解、保證代碼可靠性。設計模式使代碼編寫工程化,是軟件工程的基本脈絡
單例模式
一個類只能創建一個對象,即單例模式。該模式可以保證系統中該類只有一個實例,并提供一個訪問它的全局訪問點,該實例被所有程序模塊共享。比如在某個服務器程序中,該服務器的配置信息存放在一個文件中,這些配置數據由一個單例對象統一讀取,然后服務器進程中的其他對象再通過這個單例對象獲取這些配置信息,這種方式簡化了在復雜環境的配置管理
單例模式有兩種實現模式:
- 餓漢模式
在程序啟動的時候就創建唯一的實例對象,不管用不用
class Singleton
{
public:static Singleton* GetInstance(){return &_instance;}private://防拷貝Singleton() {};Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;static Singleton _instance;
};//入口前初始化
Singleton Singleton::_instance;
優點:簡單
缺點:導致進程啟動慢,如果由多個單例類對象實例啟動順序不確定
如果單例對象再多線程高并發環境下頻繁使用,性能要求較高,那么顯然使用餓漢模式來避免資源競爭,提高響應速度更好
- 懶漢模式
如果單例對象構造十分耗時或者占用很多資源,比如加載插件,初始化網絡連接讀取文件等,有可能對象程序運行時不會用到,那么也要在程序一開始就初始化,會導致啟動時很慢,這種情況使用懶漢模式(延遲加載)更好
class Singleton
{
public:static Singleton* GetInstance(){if (_instace == nullptr){_instace = new Singleton();}return _instace;}//資源回收class CGarbo{public:CGarbo(){if (_instace){delete _instace;}}};private:Singleton() {};Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;static Singleton* _instace;static CGarbo _garbo;
};Singleton* Singleton::_instace = nullptr;
Singleton::CGarbo _garbo; //程序結束自動調用析構釋放單例對象//獲取對象
Singleton::GetInstance();