欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺析c++函數(shù)參數(shù)和返回值

 更新時(shí)間:2023年05月20日 08:29:17   作者:Backsword  
c++一直以來是一個(gè)關(guān)注效率的代碼,這樣關(guān)于函數(shù)的參數(shù)傳遞和返回值的接收,是重中之重,這篇文章主要介紹了c++函數(shù)參數(shù)和返回值,需要的朋友可以參考下

c++函數(shù)參數(shù)和返回值

c++一直以來是一個(gè)關(guān)注效率的代碼,這樣關(guān)于函數(shù)的參數(shù)傳遞和返回值的接收,是重中之重。下文提供了一些個(gè)人的見解。

函數(shù)存儲位置

函數(shù)參數(shù)在編譯期展開,目前各平臺的編譯期均有不同。

名稱存儲位置
函數(shù)名稱和邏輯代碼段存儲
函數(shù)參數(shù)和返回值棧中或者寄存器(64位會有6個(gè)寄存器使用)
new malloc 的變量

函數(shù)參數(shù)入棧順序

微軟有幾種編譯期屬性,用來定義函數(shù)參數(shù)的順序和堆棧。

關(guān)鍵字堆棧清理參數(shù)傳遞
__cdecl調(diào)用方在堆棧上按相反順序推送參數(shù)(從右到左)
__clrcall不適用按順序?qū)?shù)加載到 CLR 表達(dá)式堆棧上(從左到右)。
__stdcall被調(diào)用方在堆棧上按相反順序推送參數(shù)(從右到左)
__fastcall被調(diào)用方存儲在寄存器中,然后在堆棧上推送
__thiscall被調(diào)用方在堆棧上推送;存儲在 ECX 中的 this 指針
__vectorcall被調(diào)用方存儲在寄存器中,然后按相反順序在堆棧上推送(從右到左)

所以直接在函數(shù)參數(shù)上,調(diào)用表達(dá)式和函數(shù)來回去值的話,非常危險(xiǎn)

初始化列表

class Init1
{
public:
    void Print()
    {
        std::cout << a << std::endl;
        std::cout << b << std::endl;
        std::cout << c << std::endl;
    }
    int c, a, b;
};

A這個(gè)類,可以通過 A a{1,2,3}; 來初始化對象。
看著很美好,但是有幾個(gè)問題需要注意。
參數(shù)是的入棧順序是跟著類的屬性的順序一致, 當(dāng)前是 c, a, b;

int i = 0;
Init1 a = {i++, i++, i++};
a.Print();

當(dāng)我如此調(diào)用的時(shí)候,得到的返回值是 1 2 0i++的執(zhí)行順序是從左到右,跟函數(shù)調(diào)用順序無關(guān)。 另外不能有 構(gòu)造函數(shù)

class Init1
	{
	public:
		Init1(int ia, int ib, int ic)
		{
			std::cout << "construct" << std::endl;
			a = ia;
			b = ib;
			c = ic;
		}
		Init1(const Init1& other)
		{
			std::cout << "copy " << std::endl;
			a = other.a;
			b = other.b;
			c = other.c;
		}
		void Print()
		{
			std::cout << a << std::endl;
			std::cout << b << std::endl;
			std::cout << c << std::endl;
		}
		int c, a, b;
	};

當(dāng)我添加了構(gòu)造函數(shù)的時(shí)候。 用下面代碼測試。會得到兩種結(jié)果

void Test_InitilizeList()
{
	int i = 0;
	//Init1 a = { i++, i++, i++ }; // 0 1 2 
	Init1 a(i++, i++, i++); // 2 1 0 
	a.Print();
}

函數(shù)的返回值

函數(shù)返回值的聲明周期在函數(shù)體內(nèi)。

用參數(shù)引用來返回

class Result
{
public:
int result;
};
void GetResult(Result& result) ...

優(yōu)點(diǎn):

  • 效率最高,因?yàn)榉祷刂档膶ο笤诤瘮?shù)體外構(gòu)造,可以一直套用, 可以一處構(gòu)造,一直使用。
  • 安全,可以定義對象,并不用new或者malloc, 沒有野指針困擾。
    缺點(diǎn):
  • 代碼可讀性低,不夠優(yōu)美
  • 無法返回nullptr. 一般在 Result 中定義一個(gè); 用來表示一個(gè)空對象。
  • 容易賦值到一個(gè)臨時(shí)對象中,當(dāng)調(diào)用GetResult({1}) 會賦值到一個(gè) 臨時(shí)的 Result 對象中,拿不到返回值。正常來說也不會這樣做。

返回一個(gè)參數(shù)指針

class Result
{
public:
int result;
};
Result* GetResult() ...

優(yōu)點(diǎn):

  • 簡潔明了
  • 參數(shù)傳遞快速
    缺點(diǎn):
  • 指針如果在 函數(shù)內(nèi) static 需要考慮多線程。 如果是 new 出來的,多次調(diào)用效率不高
  • 指針無法重復(fù)使用,(可以用 std::share_ptr 增加對象池來解決問題。但會引入新的復(fù)雜度。)
  • 需要考慮釋放的問題

返回一個(gè)對象

class Result
{
public:
int result;
};
Result GetResult() ...

優(yōu)點(diǎn):

  • 沒有內(nèi)存泄露的風(fēng)險(xiǎn)
  • 簡潔明了
    缺點(diǎn):
  • 但有個(gè)別編譯期優(yōu)化選項(xiàng)問題,會導(dǎo)致一次構(gòu)造兩次拷貝, 第一次是函數(shù)體內(nèi)對象向返回值拷貝,第二次是 返回值拷貝給外面接收參數(shù)的。
  • 開啟編譯期優(yōu)化選項(xiàng),并且是 在 return Result 的時(shí)候構(gòu)造返回對象,才能優(yōu)化。

總結(jié)

一般如果是 簡單結(jié)構(gòu)體,用 返回一個(gè)臨時(shí)對象的方式解決。
如果使用 返回一個(gè)參數(shù)指針,一般改成返回一個(gè)id,用一個(gè)manager來管理內(nèi)存機(jī)制?;蛘?共享內(nèi)存,內(nèi)存池來解決內(nèi)存泄露后續(xù)的問題
用 參數(shù)引用來返回的話,一般會這么定義 int GetResult(Result& result) 函數(shù)返回值,用來返回狀態(tài)碼,真正的數(shù)據(jù),放到 result 中。

函數(shù)的幾種變體

inline 函數(shù)

  • inline 函數(shù)是內(nèi)聯(lián)函數(shù),是編譯期優(yōu)化的一種手段,一般是直接展開到調(diào)用者代碼里,減少函數(shù)堆棧的開銷。
  • inline 標(biāo)識只是建議,并不是一定開啟內(nèi)聯(lián)。
  • 函數(shù)比較復(fù)雜或者遞歸有可能編譯期不展開。
  • dll 導(dǎo)出的時(shí)候,可以不用加導(dǎo)出標(biāo)識,會直接導(dǎo)出到目標(biāo)處。
  • inline 在msvc的平臺,只要實(shí)現(xiàn)頭文件中,加不加內(nèi)聯(lián)是一樣的. (警告頂級調(diào)到最高/Wall, 不加inline標(biāo)識的函數(shù)會提示,未使用的內(nèi)聯(lián)函數(shù)將被刪除。)
  • inline 函數(shù)比全局函數(shù)更快,但是全局函數(shù)無法定義在頭文件中(會報(bào)多重定義函數(shù)。)所以一般用class 包一層 static inline 函數(shù),用來寫工具類。

函數(shù)對象

class A {
public :
    int value;  
    int operator() (int val) {
        return value + val;
    }
}

上述代碼是一個(gè)函數(shù)對象,重載operator()得到一個(gè)函數(shù)對象。
int a = A{10}(1) 會返回11, 顯示構(gòu)造了一個(gè)A{value=10}的對象,然后調(diào)用重載函數(shù)operator(), 返回 10 + 1 = 11
上述代碼因?yàn)槭窃陬^文件實(shí)現(xiàn)的,所以編譯期會自動把operator()函數(shù)當(dāng)成inline函數(shù),執(zhí)行效率很高。

lambda 函數(shù)

lambda 其實(shí)就是一個(gè)函數(shù)對象,會在編譯期展開成一個(gè)函數(shù)對象體。

到此這篇關(guān)于c++函數(shù)參數(shù)和返回值的文章就介紹到這了,更多相關(guān)c++函數(shù)參數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • c++實(shí)現(xiàn)對輸入數(shù)組進(jìn)行快速排序的示例(推薦)

    c++實(shí)現(xiàn)對輸入數(shù)組進(jìn)行快速排序的示例(推薦)

    下面小編就為大家?guī)硪黄猚++實(shí)現(xiàn)對輸入數(shù)組進(jìn)行快速排序的示例(推薦)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-06-06
  • C語言數(shù)據(jù)存儲詳解

    C語言數(shù)據(jù)存儲詳解

    在本篇文章里小編給大家整理的是關(guān)C語言數(shù)據(jù)存儲,小編覺得這篇文章寫的很不錯(cuò),有需要的朋友們可以學(xué)習(xí)參考下,希望能夠給你帶來幫助
    2021-10-10
  • 淺談c++調(diào)用python鏈接的問題及解決方法

    淺談c++調(diào)用python鏈接的問題及解決方法

    下面小編就為大家?guī)硪黄獪\談c++調(diào)用python鏈接的問題及解決方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-03-03
  • C語言中的abs()函數(shù)和exp()函數(shù)的用法

    C語言中的abs()函數(shù)和exp()函數(shù)的用法

    這篇文章主要介紹了C語言中的abs()函數(shù)和exp()函數(shù)的用法,是C語言入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-08-08
  • 在VC中隱藏控制臺程序窗口的實(shí)現(xiàn)代碼

    在VC中隱藏控制臺程序窗口的實(shí)現(xiàn)代碼

    大家都知道,當(dāng)編寫一個(gè)win32 console application時(shí),當(dāng)運(yùn)行此類程序的時(shí)候默認(rèn)情況下會有一個(gè)類似dos窗口的console窗口,但是有的時(shí)候我們只想在程序中運(yùn)行一段功能代碼,不希望顯示這個(gè)console窗口,讓代碼執(zhí)行完畢之后程序自動退出
    2013-04-04
  • C語言do關(guān)鍵字的具體使用

    C語言do關(guān)鍵字的具體使用

    本篇文章主要介紹了C語言do關(guān)鍵字的具體使用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • OpenCV實(shí)現(xiàn)輪廓檢測與繪制

    OpenCV實(shí)現(xiàn)輪廓檢測與繪制

    這篇文章主要為大家詳細(xì)介紹了OpenCV實(shí)現(xiàn)輪廓檢測與繪制,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • C語言 完整游戲項(xiàng)目坦克大戰(zhàn)詳細(xì)代碼

    C語言 完整游戲項(xiàng)目坦克大戰(zhàn)詳細(xì)代碼

    《坦克大戰(zhàn)》以二戰(zhàn)坦克為題材,既保留了射擊類游戲的操作性,也改進(jìn)了射擊類游戲太過于復(fù)雜難玩的高門檻特點(diǎn),集休閑與競技于一身。經(jīng)典再度襲來,流暢的畫面,瘋狂的戰(zhàn)斗,讓玩家再次進(jìn)入瘋狂坦克的世界。玩家的目標(biāo)是控制坦克躲避危險(xiǎn),消滅掉所有的敵人即可進(jìn)入下一關(guān)
    2021-11-11
  • EasyC++模板重載

    EasyC++模板重載

    這篇文章主要介紹了C++模板重載,重載的模板的函數(shù)特征,也就是入?yún)⒌臄?shù)量和類型必須有所不同,下面我們講舉例說明此內(nèi)容,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2021-12-12
  • C語言基于哈希表實(shí)現(xiàn)通訊錄

    C語言基于哈希表實(shí)現(xiàn)通訊錄

    這篇文章主要為大家詳細(xì)介紹了C語言基于哈希表實(shí)現(xiàn)通訊錄,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02

最新評論