最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++特殊類設(shè)計與類型轉(zhuǎn)換詳細(xì)代碼示例

 更新時間:2026年01月07日 10:34:54   作者:XiaoHu0207  
在C++編程語言中,類類型轉(zhuǎn)換操作符是一種特殊的功能,允許我們把一個類的對象轉(zhuǎn)換為其他類型,如內(nèi)置類型、類類型或者由類型別名定義的類型,這篇文章主要介紹了C++特殊類設(shè)計與類型轉(zhuǎn)換的相關(guān)資料,需要的朋友可以參考下

常見的特殊類的設(shè)計

1.請設(shè)計一個類,不能被拷貝

拷貝只會發(fā)生在兩個場景中:拷貝構(gòu)造函數(shù)以及賦值運(yùn)算符重載,因此想要讓一個類禁止拷貝,只需要讓該類不能調(diào)用拷貝構(gòu)造函數(shù)以及賦值運(yùn)算符重載即可。

C++98寫法:

將拷貝構(gòu)造函數(shù)與賦值運(yùn)算符重載只聲明不定義,并且將其訪問權(quán)限設(shè)置為私有即可。

class CopyBan
{
	//...
private:
	CopyBan(const CopyBan& c);
	CopyBan& operator=(const CopyBan& c);
	//...
};

原因:1.設(shè)置成私有:如果只聲明沒有設(shè)置成private,用戶自己如果在類外定義了,就不能禁止拷貝了。

2.只聲明不定義:不定義是因為該函數(shù)根本不會調(diào)用,定義了其實也沒有什么意義,不寫反而還簡單,而且如果定義了就不會防止成員函數(shù)內(nèi)部拷貝了。

C++11寫法:

C++11擴(kuò)展delete的用法,delete除了釋放new申請的資源外,如果在默認(rèn)成員函數(shù)后面跟上=delete,表示讓編譯器刪除掉該默認(rèn)成員函數(shù)。

class CopyBan
{
	//...
	CopyBan(const CopyBan& c)=delete;
	CopyBan& operator=(const CopyBan& c)=delete;
	//...
};

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

實現(xiàn)方式:

1.將類的構(gòu)造函數(shù)設(shè)置為私有,拷貝構(gòu)造聲明成私有。防止別人調(diào)用拷貝在棧上生成對象。

2.提供一個靜態(tài)的成員函數(shù),在該靜態(tài)成員函數(shù)中完成堆對象的創(chuàng)建。

class HeapOnly
{
public:
	static HeapOnly* CreateHeapObj()
	{
		return new HeapOnly;
	}
private:
	HeapOnly()
	{ }

	//C++98方式
	//1.只聲明,不實現(xiàn)。因為實現(xiàn)可能會很麻煩,而你本身并不需要
	//2.聲明成私有
	HeapOnly& operator=(const HeapOnly&);

	//C++11方式
	HeapOnly& operator=(const HeapOnly&) = delete;
};

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

方法:同上述將構(gòu)造函數(shù)私有化,然后設(shè)計靜態(tài)方法創(chuàng)建對象返回即可。

class StackOnly
{
public:
	static StackOnly CreateStackObj()
	{
		return StackOnly();
	}

	//禁掉operator new可以把下面用new 調(diào)用拷貝構(gòu)造申請對象給禁掉
	//StackOnly obj = StackOnly::CreateStackObj();
	//StackOnly* ptr = new StackOnly(obj);
	void* operator new(size_t size) = delete;
	void operator delete(void* p) = delete;

private:
	StackOnly()
		:_a(0)
	{ }

	int _a;
};

4. 請設(shè)計一個類,不能被繼承

C++98方式:把類的構(gòu)造函數(shù)私有化,派生類調(diào)不到基類的構(gòu)造函數(shù)就無法繼承。

C++98中構(gòu)造函數(shù)私有化,派生類中調(diào)不到基類的構(gòu)造函數(shù),則無法繼承
class NonInherit
{
public:
	static NonInherit GetInstance()
	{
		return NonInherit();
	}
private:
	NonInherit()
	{ }
};

C++11方法:final關(guān)鍵字,final修飾類,表示該類不能被繼承。ps(final還能修飾虛函數(shù),表示該虛函數(shù)不能被重寫。)

final 關(guān)鍵字:final修飾類,表示該類不能被繼承。
class A final
{
	//..
};

5.請設(shè)計一個類,只能創(chuàng)建一個對象(單例模式)

設(shè)計模式:

設(shè)計模式(Design Pattern)是一套被反復(fù)使用、多數(shù)人知曉的、經(jīng)過分類的、代碼設(shè)計經(jīng)驗的總結(jié)。為什么會產(chǎn)生設(shè)計模式這樣的東西呢?就像人類歷史發(fā)展會產(chǎn)生兵法。最開始部落之間打仗時都是人拼人的對砍。后來春秋戰(zhàn)國時期,七國之間經(jīng)常打仗,就發(fā)現(xiàn)打仗也是有套路的,后來孫子就總結(jié)出了《孫子兵法》。孫子兵法也是類似。

使用設(shè)計模式的目的為了代碼可重用性、讓代碼更容易被他人理解、保證代碼可靠性。設(shè)計模式使代碼編寫真正工程化;設(shè)計模式是軟件工程的基石脈絡(luò),如同大廈的結(jié)構(gòu)一樣。

單例模式:

一個類只能創(chuàng)建一個對象,即單例模式。該模式可以保證系統(tǒng)中該類只有一個實例,并提供一個訪問它的全局訪問點(diǎn),該實例被所有程序模塊共享。比如:在某個服務(wù)器程序中,該服務(wù)器的配置信息存放在一個文件中,這些配置數(shù)據(jù)由一個單例對象統(tǒng)一讀取,然后服務(wù)進(jìn)程中的其他對象再通過這個單例對象獲取這些配置信息,這種方式簡化了在復(fù)雜環(huán)境下的配置管理。

單例模式有兩種實現(xiàn)模式:

1.餓漢模式

(一開始(main函數(shù)之前)就創(chuàng)建單例對象)

就是說不管你將來用還是不用,程序啟動時就會創(chuàng)建一個唯一的實例對象

餓漢模式
優(yōu)點(diǎn):簡單
缺點(diǎn):可能會導(dǎo)致進(jìn)程啟動慢,且如果有多個單例類對象實例啟動順序不確定。
class Singleton
{
public:
	static Singleton* GetInstance()
	{
		return &m_instance;
	}
private:
	//構(gòu)造函數(shù)私有化
	Singleton(){}
	
	//C++98防止拷貝
	Singleton(const Singleton&);
	Singleton& operator=(const Singleton&);

	//or

	//C++11
	Singleton(const Singleton&) = delete;
	Singleton& operator=(const Singleton&) = delete;

	static Singleton m_instance;
};

Singleton Singleton::m_instance;//在程序入口之前就完成單例對象的初始化

但是如果這個單例對象再多線程高并發(fā)環(huán)境下頻繁使用,性能要求比較高,那么顯然使用餓漢模式來避免資源競爭,提高響應(yīng)速度更好。

2.懶漢模式:

如果單例對象構(gòu)造十分耗時或者占用很多資源,比如加載插件啦,初始化網(wǎng)絡(luò)連接啦,讀取文件啦等等,而有可能該對象程序運(yùn)行時不會用到,那么也要在程序一開始就進(jìn)行初始化,就會導(dǎo)致程序啟動時非常的緩慢。所以這種情況就使用懶漢模式(延遲加載)更好。

懶漢模式也會有線程安全問題,在第一次初始化的時候要加鎖。

class Singleton
{
public:
	static Singleton* GetInstance()
	{
		注意這里一定要使用Double-Check的方式加鎖,才能保證效率和線程安全
		if (nullptr == m_pInstance)
		{
			m_mtx.lock();//or--- unique_lock<mutex> lock(m_mtx);
			if (nullptr == m_pInstance)
			{
				m_pInstance = new Singleton();
			}
			m_mtx.unlock();
		}
	}

	//實現(xiàn)一個內(nèi)嵌的垃圾回收類
	class CGarbo
	{
	public:
		~CGarbo()
		{
			if (Singleton::m_pInstance)
				delete Singleton::m_pInstance;
		}
	};
	//定義一個靜態(tài)成員變量,程序結(jié)束時,系統(tǒng)自動調(diào)用它的析構(gòu)函數(shù)從而釋放單例對象
	static CGarbo Garbo;
    main函數(shù)結(jié)束,調(diào)用它的析構(gòu),從而釋放單例對象

private:
	//構(gòu)造函數(shù)私有化
	Singleton(){}

	//防止拷貝
	Singleton(const Singleton&) = delete;
	Singleton& operator=(const Singleton&) = delete;

	static Singleton* m_pInstance;//單例對象指針
	static std::mutex m_mtx;	//互斥鎖
};

Singleton* Singleton::m_pInstance = nullptr;
Singleton::CGarbo Garbo;
std::mutex Singleton::m_mtx;

C++11中創(chuàng)建單例(懶漢模式)最簡單的方法

class Singleton
{
public:
    局部的靜態(tài)對象,是在第一次調(diào)用時初始化
	static Singleton& GetInstance()
	{
		static Singleton inst;
		return inst;
	}
private:
	Singleton()
	{
		std::cout << "Singleton" << std::endl;
	}
	Singleton(const Singleton&) = delete;
	Singleton& operator=(const Singleton&) = delete;

};

C++11之前,這個代碼是不安全的,編譯器不支持。

C++11之后,可以保證局部靜態(tài)對象的初始化是線程安全的,只初始化一次。(C++11之后這個操作變成原子的了。)

C++中的類型轉(zhuǎn)換

1.C語言中的類型轉(zhuǎn)換

在C語言中,如果賦值運(yùn)算符左右兩側(cè)類型不同,或者形參與實參類型不匹配,或者返回值類型與接收返回值類型不一致時,就需要發(fā)生類型轉(zhuǎn)換,C語言中總共有兩種形式的類型轉(zhuǎn)換:隱式類型轉(zhuǎn)換和顯式類型轉(zhuǎn)換。

1.隱式類型轉(zhuǎn)換:編譯器在編譯階段自動進(jìn)行,能轉(zhuǎn)就轉(zhuǎn),不能轉(zhuǎn)就編譯失敗。

2.顯式類型轉(zhuǎn)換:需要用戶自己處理。

void Test()
{
	int i = 1;
	//隱式類型轉(zhuǎn)換
	double d = i;
	printf("%d,%.2lf\n", i, d);

	int* p = &i;
	//顯式類型轉(zhuǎn)換
	int address = (int)p;
	printf("%x,%d\n", p, address);
}

缺陷:轉(zhuǎn)換的可視性比較差,所有的轉(zhuǎn)換形式都是以一種相同形式書寫,難以跟蹤錯誤的轉(zhuǎn)換。

2.為什么C++需要四種類型轉(zhuǎn)換

C風(fēng)格的轉(zhuǎn)換形式很簡單,但是有不少缺點(diǎn):

1.隱式類型轉(zhuǎn)換有些情況下可能會出問題:比如說數(shù)據(jù)精度的丟失。

2.顯式類型轉(zhuǎn)換將所有情況混合在一起,代碼不夠清晰。

因此C++提出了自己的類型轉(zhuǎn)換的風(fēng)格,注意C++要兼容C語言,所以在C++中還是可以使用C語言那一套的類型轉(zhuǎn)換。

3.C++強(qiáng)制類型轉(zhuǎn)換

標(biāo)準(zhǔn)C++為了加強(qiáng)類型轉(zhuǎn)換的可視性,引入了四種命名的強(qiáng)制類型轉(zhuǎn)換操作符:

static_cast , reinterpret_cast  , const_cast  , dynamic_cast

3.1 stacit_cast

static_cast用于非多態(tài)類型的轉(zhuǎn)換(靜態(tài)轉(zhuǎn)換),編譯器隱式執(zhí)行的任何類型轉(zhuǎn)換都可用static_cast但它不能用于兩個不相關(guān)的類型進(jìn)行轉(zhuǎn)換。(用于兩個相關(guān)類型/相近類型之間,C里的隱式類型轉(zhuǎn)換都可用這個static_cast強(qiáng)轉(zhuǎn)。

int main()
{
	double d = 12.34;
	int a = static_cast<int>(d);
	std::cout << a << std::endl;
	return 0;
}

3.2 reinterpret_cast

reinterpret_cast操作符通常為操作數(shù)的位模式提供較低層次的重新解釋,用于將一種類型轉(zhuǎn)換為另一種不同的類型。(可用于兩個不相關(guān)類型之間進(jìn)行強(qiáng)轉(zhuǎn)。

int main()
{
	double d = 12.34;
	int a = static_cast<int>(d);
	std::cout << a << std::endl;
	
	這里使用static_cast會報錯,應(yīng)該使用reinterpret
	//int* p = static_cast<int*>(a);
	int* p = reinterpret_cast<int*>(a);

	return 0;
}

3.3 const_cast

const_cast最常用的用途就是刪除變量的const屬性,方便賦值。(去掉const屬性。

int main()
{
	const int a = 2;
	int* p = const_cast<int*>(&a);
	*p = 3;
	std::cout << a << std::endl;

	return 0;
}

3.4 dynamic_cast

dynamic_cast用于將一個父類對象的指針/引用轉(zhuǎn)換為子類對象的指針或引用(動態(tài)轉(zhuǎn)換)。

向上轉(zhuǎn)型:子類對象指針/引用 ->父類指針/引用(不需要轉(zhuǎn)換,賦值兼容規(guī)則)。

向下轉(zhuǎn)型:父類對象指針/引用->子類指針/引用(用dynamic_cast轉(zhuǎn)型是安全的)。

注意:

1.dynamic_cast只能用于父類含有虛函數(shù)的類。

2.dynamic_cast會先檢查是否能轉(zhuǎn)換成功,能成功則轉(zhuǎn)換,不能則返回0。

Base* b = new Derived();  b實際上指向Derived對象

 情況1:成功轉(zhuǎn)換
Derived* d1 = dynamic_cast<Derived*>(b);  
 成功:b實際指向Derived對象,d1是有效的Derived指針

 情況2:轉(zhuǎn)換失敗
Base* b2 = new Base();  // b2指向純Base對象
Derived* d2 = dynamic_cast<Derived*>(b2);
 失?。篵2不是Derived對象,d2 == nullptr
class A
{
public:
	virtual void f(){}
};

class B :public A
{};

void fun(A* pa)
{
	//dynamic_cast會先檢查是否能成功轉(zhuǎn)換成功,能成功則轉(zhuǎn)換,不能則返回
	B* pb1 = static_cast<B*>(pa);
	B* pb2 = dynamic_cast<B*>(pa);

	std::cout << "pb1:" << pb1 << std::endl;
	std::cout << "pb2:" << pb2 << std::endl;
}

int main()
{
	A a;
	B b;
	fun(&a);
	fun(&b);
	return 0;
}

注意:

強(qiáng)制類型轉(zhuǎn)換關(guān)閉或掛起了正常的類型檢查,每次使用強(qiáng)制類型轉(zhuǎn)換前,程序員應(yīng)該仔細(xì)考慮是否還有其他不同的方法達(dá)到同一目的,如果非強(qiáng)制類型轉(zhuǎn)換不可,則應(yīng)限制強(qiáng)制類型轉(zhuǎn)換值的作用域,以減少發(fā)生錯誤的機(jī)會。強(qiáng)烈建議:避免使用強(qiáng)制類型轉(zhuǎn)換。

4.RTTI(了解)

RTTI:Run-time Type identification的簡稱,即:運(yùn)行時類型識別。

C++通過一下方式來支持RTTI:

1.typeid運(yùn)算符。

2.dynamic_cast運(yùn)算符。

3.decltype。

5.常見面試題

1.C++中的四種類型轉(zhuǎn)換分別是:static_cast,reinterpret_cast,const_cast,dynamic_cast。

2.說說四種類型轉(zhuǎn)換的應(yīng)用場景。

static_cast適用于兩種類型相近的強(qiáng)制轉(zhuǎn)化,dynamic_cast適用于多態(tài)類型的向下轉(zhuǎn)換(安全檢查)(向上轉(zhuǎn)換本來就是安全的)。cosnt_cast適用于刪除變量的const屬性。reinterpret_cast適用于任意類型之間的轉(zhuǎn)換(危險)。

總結(jié) 

到此這篇關(guān)于C++特殊類設(shè)計與類型轉(zhuǎn)換的文章就介紹到這了,更多相關(guān)C++特殊類設(shè)計與類型轉(zhuǎn)換內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++數(shù)據(jù)結(jié)構(gòu)之AVL樹的實現(xiàn)

    C++數(shù)據(jù)結(jié)構(gòu)之AVL樹的實現(xiàn)

    AVL樹是高度平衡的而二叉樹,它的特點(diǎn)是AVL樹中任何節(jié)點(diǎn)的兩個子樹的高度最大差別為1,本文主要給大家介紹了C++如何實現(xiàn)AVL樹,需要的朋友可以參考下
    2022-06-06
  • Windows進(jìn)程崩潰問題的定位方法

    Windows進(jìn)程崩潰問題的定位方法

    這篇文章主要介紹了Windows進(jìn)程崩潰問題的定位方法,本文使用nstd工具進(jìn)行進(jìn)程崩潰時內(nèi)存和堆棧轉(zhuǎn)儲的方法查明問題所在,需要的朋友可以參考下
    2015-04-04
  • Cocos2d-x學(xué)習(xí)筆記之Hello World源碼分析

    Cocos2d-x學(xué)習(xí)筆記之Hello World源碼分析

    這篇文章主要介紹了Cocos2d-x學(xué)習(xí)筆記之Hello World源碼分析,接上一篇內(nèi)容,本文著重分析源碼文件,需要的朋友可以參考下
    2014-09-09
  • 基于C++實現(xiàn)日期計算器的詳細(xì)教程

    基于C++實現(xiàn)日期計算器的詳細(xì)教程

    在現(xiàn)代社會中,計算器已經(jīng)進(jìn)入了每一個家庭,人們在生活和學(xué)習(xí)中經(jīng)常需要使用到計算器,下面這篇文章主要給大家介紹了關(guān)于基于C++實現(xiàn)日期計算器的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • C語言 文件操作解析詳解及實例代碼

    C語言 文件操作解析詳解及實例代碼

    這篇文章主要介紹了C語言 文件操作解析詳解及實例代碼的相關(guān)資料,需要的朋友可以參考下
    2016-11-11
  • QT移植到RK3568開發(fā)板的方法步驟

    QT移植到RK3568開發(fā)板的方法步驟

    本文主要介紹了QT移植到RK3568開發(fā)板的方法步驟,文中通過圖文示例介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-03-03
  • 帶你用C語言實現(xiàn)strtok和字符串分割函數(shù)

    帶你用C語言實現(xiàn)strtok和字符串分割函數(shù)

    下面小編就為大家?guī)硪黄猚語言中字符串分割函數(shù)及實現(xiàn)方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2021-09-09
  • C語言中動態(tài)內(nèi)存管理圖文詳解

    C語言中動態(tài)內(nèi)存管理圖文詳解

    在編寫程序時,通常并不知道需要處理的數(shù)據(jù)量,或者難以評估所需處理數(shù)據(jù)量的變動程度,下面這篇文章主要給大家介紹了關(guān)于C語言中動態(tài)內(nèi)存管理的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • 淺析C++中dynamic_cast和static_cast實例語法詳解

    淺析C++中dynamic_cast和static_cast實例語法詳解

    這篇文章主要介紹了淺析C++中dynamic_cast和static_cast實例演示,包括static_cast語法知識和static_cast的作用講解,namic_cast 語法詳解,需要的朋友可以參考下
    2021-07-07
  • C++超集C++/CLI模塊的基本用法

    C++超集C++/CLI模塊的基本用法

    這篇文章介紹了C++超集C++/CLI模塊的基本用法,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07

最新評論

华蓥市| 伊吾县| 平陆县| 正宁县| 扎鲁特旗| 巴东县| 广东省| 禄丰县| 陇川县| 高青县| 普兰店市| 和田县| 来安县| 云阳县| 杭锦后旗| 溆浦县| 台州市| 湘阴县| 克拉玛依市| 大洼县| 三门峡市| 安平县| 霞浦县| 乐都县| 宣武区| 新宁县| 吉林市| 涿鹿县| 义乌市| 巴彦县| 华阴市| 原平市| 安顺市| 甘德县| 古交市| 宁强县| 平乡县| 赤壁市| 汉沽区| 普陀区| 民权县|