国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

c++學習之特殊類設計與類型轉換

這篇具有很好參考價值的文章主要介紹了c++學習之特殊類設計與類型轉換。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1.設計一個類,無法被拷貝。

方法:c++98,通過私有且只申明不實現(xiàn)拷貝構造與賦值函數,從而實現(xiàn)該類不能被拷貝。c++11引入關鍵字delete后,可以使構造構造與賦值函數等于delete。效果也是無法被拷貝。

2.設計一個類只能在堆上創(chuàng)建對象。

方法一,析構私有化

//實現(xiàn)一個類,智能在堆上創(chuàng)建對象
class HeapCreat
{
public:
	
	HeapCreat()
	{
		cout << "調用構造" << endl;
	}
	void release()
	{
		delete this;
	}
private:
	//方法一 析構函數私有化   
	~HeapCreat()
	{
		cout << "調用析構" << endl;
	}
	

方法二,構造私有化

class HeapCreat
{
public:
    ~HeapCreat()
	{
		cout << "調用析構" << endl;
	}
	void release()
	{
		delete this;
	}
	static HeapCreat* Creat()
	{
		return new HeapCreat;
	}
    //但是要禁用拷貝構造,拷貝出都在棧上,不在堆上
      HeapCrea(const HeapCrea& p)=delete;
     
private:
	HeapCreat()
	{
		cout << "調用構造" << endl;
	}
	//方案二 構造函數私有化
};

int main()
{
	//構造函數私有化,最開始都初始化不了,因此只能在類里初始化,并且申明為全局,之后調用類里的初始化
	HeapCreat* p = HeapCreat::Creat();
	p->release();
	return 0;

}

3.設計一個類只能在棧上創(chuàng)建對象。

方法一:

還是構造私有化,但是注意拷貝構造,我們拷貝構造可以new,但拷貝構造不能禁用,因為我們需要調用拷貝構造,故有缺陷

//構造私有化
//還是控制構造函數,在類中實現(xiàn)只能在棧上創(chuàng)建。
class HeapCreat
{
public:
    ~HeapCreat()
	{
		cout << "調用析構" << endl;
	}
	
	static HeapCreat Creat()
	{
		return  HeapCreat();
	}
    HeapCreat( HeapCreat& p)=delete;
private:
	HeapCreat()
	{
		cout << "調用構造" << endl;
	}
};

int main()
{
	HeapCreat p = HeapCreat::Creat();
	return 0;
}

方法二,直接不讓使用new,申明出new并私有化,或delete.

class HeapCreat
{
public:
    ~HeapCreat()
	{
		cout << "調用析構" << endl;
	}
	
	static HeapCreat Creat()
	{
		return  HeapCreat();
	}
	void* operator new(size_t t) = delete;
	
private:
	//void* operator new(size_t t) 
	HeapCreat()
	{
		cout << "調用構造" << endl;
	}
};

4.設計一個類,不能被繼承

同上,構造函數私有化,調不了就無法被繼承。

c++11提供了關鍵字final,可以是這個類不能為繼承,即最終類。

?一,何為設計模式

? ? 設計模式是軟件開發(fā)人員在軟件開發(fā)過程中面臨的一般問題的解決方案。設計模式代表了最佳的實踐,通常被有經驗的面向對象的軟件開發(fā)人員所采用。就是前人總結下來的一些經驗。

設計模式分為三大類:創(chuàng)建型模式、結構型模式和行為型模式。

創(chuàng)建型模式包括工廠方法模式、抽象工廠模式、單例模式、建造者模式和原型模式。結構型模式包括適配器模式、橋接模式、組合模式、裝飾模式、外觀模式、享元模式和代理模式。行為型模式包括責任鏈模式、命令模式、解釋器模式、迭代器模式、中介者模式、備忘錄模式、觀察者模式、狀態(tài)模式、策略模式、模板方法模式和訪問者模式。

而創(chuàng)作型中常用的就是我們的單例模式,我們以學習單例模式來了解一下設計模式。

二,單例模式

所謂的單例模式其實本質上就是一個特殊類的設計。對于單例模式,在整個進程中,在整個全局環(huán)境中,只有這一個實例化的對象,即單實例,對于這樣的類的設計就是單例模式。對于大一點的項目,內存池等都會用到單例模式。

那么如是設計出全局下只有一個實例化對象?參考前面的博客,,特殊類的設計,那么要想只能實例化出一個對象,且是在全局的環(huán)境下,首先,我們要控制構造函數,讓其私有化,這樣在外面就無法實例化,對于構造提供了兩種方式,也就是單例模式的兩種模式。

其次就是要求在全局環(huán)境下的對象,直接在全局下創(chuàng)建首先無法實例化,構造函數已經私有化了,

且全局的對象是存在弊端的:對象是容易被修改的,多線程下會出現(xiàn)鏈接問題等。

之后了我們在類里創(chuàng)建對象,但直接創(chuàng)建顯然不可行,自己創(chuàng)建自己,但是當我們使用ststic時,就不是自己創(chuàng)建自己,該對象是在靜態(tài)區(qū)中。

因此最終我們選用靜態(tài)全局的方式實現(xiàn)單例模式。

餓漢模式

顧名思義,該模式很“饑餓”,我們在進入主程序前,就要把這個特殊類設計好給我,也就是在此之前,把對象給我來用。

class TEST
{
public:
	//一般我們通過接口Getinstance 來獲取這個對象

	static TEST* GetInstance()  //對象是靜態(tài)對象
	{
		return  &test;
	}
	void ADD(const string key, const string val)
	{ 
		dict.insert(make_pair(key, val));
	}

	void Print()
	{
		for (auto it : dict)
		{
			cout << it.first << ":" << it.second<<endl;
		}
	}
private:
 //首先類的成員一般都是私有的,這里以一個字典為例
	map <string, string> dict;
	//私有構造并禁用拷貝與賦值
	TEST()
	{

	}
	TEST(const TEST& p) = delete;
	TEST& operator=(const TEST& p) = delete;

	static TEST test;//聲明   在靜態(tài)區(qū)當中
};
//定義
TEST TEST::test;   //定義了一個類的對象test

int main()
{
	//程序啟動 餓漢模式
	TEST::GetInstance()->ADD("冒泡", "排序");//通過GetInstance獲取唯一的對象test
	TEST::GetInstance()->ADD("希爾", "排序");
	TEST::GetInstance()->Print();
	return 0;
}

優(yōu)缺點:

優(yōu)點:實現(xiàn)簡單

缺點:可能導致進程啟動 ,如果有兩個單例啟動具有先后順序,控制不了餓漢。

懶漢模式

顧名思義,現(xiàn)吃現(xiàn)做,只有當我們需要使用這個對象的時候,我們才提供對象。即第一次使用的時候才創(chuàng)建。

//懶漢模式
class TEST
{
public:
	
	static TEST* GetInstance()  
	{
		//主程序要調用使用對象了此時我們在創(chuàng)建
		//這里主要介紹懶漢的思想,實際上這里的代碼還存在線程安全問題
		if (test == nullptr)
		{
			test = new TEST;
		}
		return test;
	}
	void ADD(const string key, const string val)
	{ 
		dict.insert(make_pair(key, val));
	}

	void Print()
	{
		for (auto it : dict)
		{
			cout << it.first << ":" << it.second<<endl;
		}
	}
	static void Delete()
	{
		if (test)
		{
			delete test;
			test = nullptr;
		}
	}
	
private:
 //這里以一個字典為例
	map <string, string> dict;
    ~TEST()
	{
		delete test;
	}
	TEST()
	{

	}
	TEST(const TEST& p) = delete;
	TEST& operator=(const TEST& p) = delete;
	static TEST *test;//聲明   在靜態(tài)區(qū)當中
	class gc
	{
	public:
		~gc()
		{
			Delete();
		}
		
	};
	static gc _gc;
};
//定義
TEST* TEST::test=nullptr;  
TEST::gc  TEST::_gc;

int main()
{
	//程序啟動 
	//懶漢模式
	TEST::GetInstance()->ADD("冒泡", "排序");//通過GetInstance獲取唯一的對象test
	TEST::GetInstance()->ADD("希爾", "排序");
	TEST::GetInstance()->Print();
	
}

釋放的時候,可以使用智能指針來管理這個指針,也可以在搞一個類用來處理析構,在該對象中,只要釋放,就會調用里面的類的的析構使得釋放指針。

類型轉換

c語言中的類型轉換

c語言的類型轉換分為兩種:

1.隱式類型轉換? :int i=1;double b=i;

對于能相互轉換的類型,可以隱式類型轉換。

2.顯式類型轉換 :? int j=1;doule ret=double(j)/0.1;

有關聯(lián)性的類型可以強制類型轉換。

c++的類型轉換

對于c語言的類型轉換,c++認為不太規(guī)范,因此c++提出了四種強制類型轉換的類型,只有這四類的類型才能強轉。

C++提供了四種強制類型轉換的函數:static_cast、dynamic_cast、const_cast和reinterpret_cast。

下面對這四種轉換操作的適用場景分別進行說明:

static_cast(靜態(tài)轉化): 該運算符把 expression 轉換為 type 類型,主要用于基本數據類型之間的轉換,如把 uint 轉換為 int,把 int 轉換為 double 等。此外,還可用于類層次結構中,基類和派生類之間指針或引用的轉換。

主要用于相近類型的轉化(對應c語言的隱式類型轉換的類型):

double i = 3.14159265;
int j = static_cast<int> (i) ;

dynamic_cast:(動態(tài)轉化) 主要用于類層次間的上行轉換或下行轉換。在進行上行轉換時dynamic_cast 和 static_cast 的效果是一樣的,但在下行轉換時,dynamic_cast 具有類型檢查的功能,比 static_cast 更安全。

dynamic_cast 用于將一個父類對象的指針 / 引用轉換為子類對象的指針或引用 ( 動態(tài)轉換 )
對于向下轉型(即父類給給子類),強制類型轉換理論上對象是不可以的,但指針和引用可以。 但是向下轉換,存在越界訪問的問題,是不安全的。
因此c++提供了dynamic_cast:
向上轉型:子類對象指針/引用->父類指針/引用(不需要轉換,賦值兼容規(guī)則)
向下轉型:父類對象指針/引用->子類指針/引用(用dynamic_cast轉型是安全的)
注意:
1. dynamic_cast 只能用于父類含有虛函數的類
i 2. dynamic_cast 會先檢查是否能轉換成功,能成功則轉換,不能則返回 0
注意使用dynamic_cast前提是多態(tài)。

const_cast:(常態(tài)轉化) 該運算符用來修改 expression 的 const 或 volatile 屬性。

去調const屬性,取地址在強轉為普通指針類型。


	const int a = 10;
	int* p = const_cast<int*>(&a);
	*p = 3;

這里的a可能直接放寄存器了,也可能宏定義了。(不再去內存找這個值)?

因此雖然這里&a與p的地址一樣,但是值不一樣。利用關鍵字volatile使得強制去內存取值,我們就會發(fā)現(xiàn)兩個值是一樣的。其次在打印&a時,注意用printf,c++中的cout的輸出流在打印時沒有對應的函數。

reinterpret_cast: (重新詮釋轉化)該運算符可以把一個指針轉換成一個整數,也可以把一個整數轉換成一個指針。這個轉換是“最不安全”的,不推薦使用

有一定關聯(lián),但是意義不相似的類型之間的轉換


	int a = 1;
	int* ptr = reinterpret_cast<int*> (a);

注意:類型轉換中間會產生臨時變量,二臨時變量具有常性,是不能被修改的(引用)。文章來源地址http://www.zghlxwxcb.cn/news/detail-808513.html

RTTI(了解)

RTTI Run-time Type identification 的簡稱,即:運行時類型識別。
C++ 通過以下方式來支持 RTTI
1. typeid 運算符
2. dynamic_cast 運算符
3. decltype

到了這里,關于c++學習之特殊類設計與類型轉換的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • C++特殊類的設計與類型轉換

    C++特殊類的設計與類型轉換

    通過new創(chuàng)建的類就是堆上的。 方法一: 這里主要以封禁構造函數為主,讓外部只能通過調用func函數方式去創(chuàng)建對象,func函數的內部是通過new創(chuàng)建的,這里要注意的就是拷貝構造的問題。 賦值重載不用刪除,因為需要現(xiàn)有一個對象才能賦值給另一個對象,上面的代碼只會創(chuàng)

    2024年02月08日
    瀏覽(16)
  • 【C++】特殊類設計+類型轉換+IO流

    【C++】特殊類設計+類型轉換+IO流

    ??個人主頁:平凡的小蘇 ??學習格言:命運給你一個低的起點,是想看你精彩的翻盤,而不是讓你自甘墮落,腳下的路雖然難走,但我還能走,比起向陽而生,我更想嘗試逆風翻盤 。 ?? C++專欄 : C++內功修煉基地 家人們更新不易,你們的??點贊??和?關注?真的對我真

    2024年02月05日
    瀏覽(17)
  • C++:特殊類的設計和類型轉換

    1.設計一個類,不能被拷貝 拷貝只會放生在兩個場景中: 拷貝構造函數以及賦值運算符重載 ,因此想要讓一個類禁止拷貝,只需讓該類不能調用拷貝構造函數以及賦值運算符重載即可。 2.設計一個類,只能在堆上創(chuàng)建對象 兩種實現(xiàn)方式: 將類的 構造函數私有 , 拷貝構造聲

    2024年01月24日
    瀏覽(23)
  • 從C語言到C++_37(特殊類設計和C++類型轉換)單例模式

    從C語言到C++_37(特殊類設計和C++類型轉換)單例模式

    目錄 1. 特殊類設計 1.1 不能被拷貝的類 1.2 只能在堆上創(chuàng)建的類 1.3 只能在棧上創(chuàng)建的類 1.4 不能被繼承的類 1.5 只能創(chuàng)建一個對象的類(單例模式)(重點) 1.5.1 餓漢模式 1.5.2?懶漢模式 2.?類型轉換 2.1 static_cast 2.2 reinterpret_cast 2.3 const_cast 2.4 dynamic_cast 3. RTTI(了解)和類型轉換常見面

    2024年02月10日
    瀏覽(26)
  • 【C++】異常+智能指針+特殊類和類型轉換

    【C++】異常+智能指針+特殊類和類型轉換

    上天可能覺得我太孤獨,派你來和我一起對抗虛無。 1. C語言傳統(tǒng)處理錯誤的方式無非就是返回錯誤碼或者直接是終止運行的程序。例如通過assert來斷言,但assert會直接終止程序,用戶對于這樣的處理方式是難以接受的,比如用戶誤操作了一下,那app直接就終止退出了嗎?這

    2024年02月08日
    瀏覽(17)
  • 【C++學習筆記】特殊類設計

    C++類中只有兩個拷貝的方式:拷貝構造函數和賦值運算符重載。想要設計一個不能被拷貝的類,只要想辦法讓類中這兩種拷貝的方式不能使用即可。 因為在C++的類中,這兩種拷貝的方式是默認存在的,所以需要在類中只聲明不定義即可。 但是由于在用戶在類外還能定義,所

    2024年02月15日
    瀏覽(20)
  • c++學習(特殊類設計)[30]

    c++學習(特殊類設計)[30]

    如果你想要確保對象只能在堆上創(chuàng)建,可以通過將析構函數聲明為私有,并提供一個靜態(tài)成員函數來創(chuàng)建對象。這樣,類的實例化只能通過調用靜態(tài)成員函數來完成,而無法直接在棧上創(chuàng)建對象。 以下是一個示例: 在上面的示例中, HeapOnlyClass 類的構造函數和析構函數都被

    2024年02月14日
    瀏覽(16)
  • 【C++學習】C++4種類型轉換詳解

    【C++學習】C++4種類型轉換詳解

    在C語言中,如果賦值運算符左右兩側類型不同,或者形參與實參類型不匹配,或者返回值類型與接收返回值類型不一致時,就需要發(fā)生類型轉化,C語言中總共有兩種形式的類型轉換:隱式類型轉換和顯式類型轉換。 隱式類型轉化:編譯器在編譯階段自動進行,能轉就轉,不

    2024年04月28日
    瀏覽(33)
  • web前端框架JS學習之JavaScript類型轉換

    web前端框架JS學習之JavaScript類型轉換

    vascript有多種數據類型,如字符串、數字、布爾等,可以通過typeof語句來查看變量的數據類型。數據類型轉換就是數據類型之間相互轉換,比如把數字轉成字符串、把布爾值轉成字符串、把字符串轉成數字等,這在工作也是經常碰到的。 本期我們就給大家說說web前端框架JS學

    2024年02月10日
    瀏覽(90)
  • 【C++】特殊類設計

    【C++】特殊類設計

    歡迎來到Cefler的博客?? ??博客主頁:折紙花滿衣 ??個人專欄:題目解析 ??推薦文章:【LeetCode】winter vacation training 拷貝只會放生在兩個場景中: 拷貝構造函數 以及 賦值運算符重載 ,因此想要讓一個類禁止拷貝, 只需讓該類不能調用拷貝構造函數以及賦值運算符重載即

    2024年01月17日
    瀏覽(45)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包