溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

c++如何禁止函數(shù)的傳值調(diào)用操作

發(fā)布時(shí)間:2020-08-12 11:56:38 來源:億速云 閱讀:214 作者:小新 欄目:開發(fā)技術(shù)

這篇文章主要介紹了c++如何禁止函數(shù)的傳值調(diào)用操作,具有一定借鑒價(jià)值,需要的朋友可以參考下。希望大家閱讀完這篇文章后大有收獲。下面讓小編帶著大家一起了解一下。

代碼編譯運(yùn)行環(huán)境:VS2017+Debug+Win32

按照參數(shù)形式的不同,C++應(yīng)該有三種函數(shù)調(diào)用方式:傳值調(diào)用、引用調(diào)用和指針調(diào)用。對(duì)于基本數(shù)據(jù)類型的變量作為實(shí)參進(jìn)行參數(shù)傳遞時(shí),采用傳值調(diào)用與引用調(diào)用和指針調(diào)用的效率相差不大。但是,對(duì)于類類型來說,傳值調(diào)用和引用調(diào)用之間的區(qū)別很大,類對(duì)象的尺寸越大,這種差別越大。

傳值調(diào)用與后面兩者的區(qū)別在于傳值調(diào)用在進(jìn)入函數(shù)體之前,會(huì)在棧上建立一個(gè)實(shí)參的副本,而引用和指針調(diào)用沒有這個(gè)動(dòng)作。建立副本的操作是利用拷貝構(gòu)造函數(shù)進(jìn)行的。因此,要禁止傳值調(diào)用,就必須在類的拷貝構(gòu)造函數(shù)上做文章。

可以直接在拷貝構(gòu)造函數(shù)中拋出異常,這樣就迫使程序員不能使用拷貝構(gòu)造函數(shù),否則程序總是出現(xiàn)運(yùn)行時(shí)錯(cuò)誤。但是,這不是一個(gè)好的辦法,應(yīng)該在編譯的階段就告訴程序員,不能使用該類的拷貝構(gòu)造函數(shù)。

1.不顯示定義拷貝構(gòu)造函數(shù)可行嗎?

#include <iostream>
using namespace std;

class A
{
public:
	int num;
	A(){num=5;}
};

void show(A a)
{
	cout<<a.num<<endl;
}

int main()
{
	A obj;
	show(obj);
}

以上程序順利通過編譯,并輸出5。因此,不顯示定義拷貝構(gòu)造函數(shù),并不能阻止對(duì)類的拷貝構(gòu)造函數(shù)的調(diào)用,原因是編譯器會(huì)自動(dòng)為沒有顯示定義拷貝構(gòu)造函數(shù)的類提供一個(gè)默認(rèn)的拷貝構(gòu)造函數(shù)。

2.顯示定義拷貝構(gòu)造函數(shù)并將訪問權(quán)限設(shè)置為private

上面的程序添加拷貝構(gòu)造函數(shù)的定義,修改如下。

#include <iostream>
using namespace std;

class A
{
	A(const A&){};
public:
	int num;
	A(){num=5;}

};

void show(A a)
{
	cout<<a.num<<endl;
}

int main()
{
	A obj;
	show(obj);
}

這個(gè)程序在VS2017環(huán)境下編譯不通過,得到如下錯(cuò)誤:error C2248: “A::A”: 無法訪問 private 成員(在“A”類中聲明)。
 這樣就能阻止了函數(shù)調(diào)用時(shí),類A的對(duì)象以值傳遞的方式進(jìn)行函數(shù)函數(shù)調(diào)用。為使程序通過編譯,需將show()函數(shù)的定義改為如下形式:

void show(const A& a)
{
	cout<<a.num<<endl;
}

3.拷貝構(gòu)造函數(shù)的說明

(1)如果將拷貝構(gòu)造函數(shù)中的引用符號(hào)去掉&,編譯將無法通過,出錯(cuò)的信息如下:非法的復(fù)制構(gòu)造函數(shù): 第一個(gè)參數(shù)不應(yīng)是“A”。原因是如果拷貝構(gòu)造函數(shù)中的參數(shù)不是一個(gè)引用,即形如A(const A a),那么就相當(dāng)于采用了傳值的方式(pass-by-value),而傳值的方式會(huì)調(diào)用該類的拷貝構(gòu)造函數(shù),從而造成無窮遞歸地調(diào)用拷貝構(gòu)造函數(shù)。因此拷貝構(gòu)造函數(shù)的參數(shù)必須是一個(gè)引用或一個(gè)指針。

(2)拷貝構(gòu)造函數(shù)的參數(shù)通常情況下是const的,但是const并不是嚴(yán)格必須的。

(3)附帶說明,在下面幾種情況下會(huì)調(diào)用拷貝構(gòu)造函數(shù):

 a. 顯式或隱式地用同類型的一個(gè)對(duì)象來初始化另外一個(gè)對(duì)象;
 b. 作為實(shí)參以值傳遞的方式傳遞給一個(gè)函數(shù);
 c. 在函數(shù)體內(nèi)返回一個(gè)對(duì)象時(shí),也會(huì)調(diào)用返回值類型的拷貝構(gòu)造函數(shù);
 d. 需要產(chǎn)生一個(gè)臨時(shí)類對(duì)象時(shí)(類對(duì)象作為函數(shù)返回值會(huì)創(chuàng)建臨時(shí)對(duì)象)。

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享c++如何禁止函數(shù)的傳值調(diào)用操作內(nèi)容對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,遇到問題就找億速云,詳細(xì)的解決方法等著你來學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI