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

詳解C++編程中向函數(shù)傳遞引用參數(shù)的用法

 更新時(shí)間:2016年01月25日 16:09:42   投稿:goldensun  
這篇文章主要介紹了詳解C++編程中向函數(shù)傳遞引用參數(shù)的用法,包括使函數(shù)返回引用類型以及對(duì)指針的引用,需要的朋友可以參考下

引用類型的函數(shù)參數(shù)
向函數(shù)傳遞引用而非大型對(duì)象的效率通常更高。 這使編譯器能夠在保持已用于訪問(wèn)對(duì)象的語(yǔ)法的同時(shí)傳遞對(duì)象的地址。 請(qǐng)考慮以下使用了 Date 結(jié)構(gòu)的示例:

// reference_type_function_arguments.cpp
struct Date
{
short DayOfWeek;
short Month;
short Day;
short Year;
};

// Create a Julian date of the form DDDYYYY
// from a Gregorian date.
long JulianFromGregorian( Date& GDate )
{
static int cDaysInMonth[] = {
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  };
long JDate = 0;
// Add in days for months already elapsed.
for ( int i = 0; i < GDate.Month - 1; ++i )
JDate += cDaysInMonth[i];
// Add in days for this month.
JDate += GDate.Day;

// Check for leap year.
if ( GDate.Year % 100 != 0 && GDate.Year % 4 == 0 )
JDate++;
// Add in year.
JDate *= 10000;
JDate += GDate.Year;

return JDate;
}

int main()
{
}

前面的代碼顯示通過(guò)引用傳遞的結(jié)構(gòu)的成員是通過(guò)成員選擇運(yùn)算符 (.) 訪問(wèn)的,而不是通過(guò)指針成員選擇運(yùn)算符 (–>) 訪問(wèn)的。
盡管作為引用類型傳遞的參數(shù)遵循了非指針類型的語(yǔ)法,但它們?nèi)匀槐A袅酥羔橆愋偷囊粋€(gè)重要特征:除非被聲明為 const,否則它們是可以修改的。 由于上述代碼的目的不是修改對(duì)象 GDate,因此更合適的函數(shù)原型是:

long JulianFromGregorian( const Date& GDate );

此原型將確保函數(shù) JulianFromGregorian 不會(huì)更改其參數(shù)。
任何其原型采用引用類型的函數(shù)都能接受其所在位置的相同類型的對(duì)象,因?yàn)榇嬖趶?typename 到 typename& 的標(biāo)準(zhǔn)轉(zhuǎn)換。

引用類型函數(shù)返回
可將函數(shù)聲明為返回引用類型。 做出此類聲明原因有:

  • 返回的信息是一個(gè)返回引用比返回副本更有效的足夠大的對(duì)象。
  • 函數(shù)的類型必須為左值。
  • 引用的對(duì)象在函數(shù)返回時(shí)不會(huì)超出范圍。

就像通過(guò)引用傳遞大型對(duì)象 to 函數(shù)或返回大型對(duì)象 from 函數(shù)可能更有效。 引用返回協(xié)議使得不必在返回前將對(duì)象復(fù)制到臨時(shí)位置。

當(dāng)函數(shù)的計(jì)算結(jié)果必須為左值時(shí),引用返回類型也可能很有用。 大多數(shù)重載運(yùn)算符屬于此類別,尤其是賦值運(yùn)算符。 重載運(yùn)算符在重載運(yùn)算符中有述。
示例
請(qǐng)考慮 Point 示例:

// refType_function_returns.cpp
// compile with: /EHsc

#include <iostream>
using namespace std;

class Point
{
public:
// Define "accessor" functions as
// reference types.
unsigned& x();
unsigned& y();
private:
// Note that these are declared at class scope:
unsigned obj_x; 
unsigned obj_y; 
};

unsigned& Point :: x()
{
return obj_x;
}
unsigned& Point :: y()
{
return obj_y;
}

int main()
{
Point ThePoint;
// Use x() and y() as l-values.
ThePoint.x() = 7;
ThePoint.y() = 9;

// Use x() and y() as r-values.
cout << "x = " << ThePoint.x() << "\n"
<< "y = " << ThePoint.y() << "\n";
}

輸出

 x = 7
y = 9

請(qǐng)注意,函數(shù)x 和 y 被聲明為返回引用類型。 這些函數(shù)可在賦值語(yǔ)句的每一端上使用。
另請(qǐng)注意在 main 中,ThePoint 對(duì)象停留在范圍中,因此其引用成員仍處于活動(dòng)狀態(tài),可以安全地訪問(wèn)。
除以下情況之外,引用類型的聲明必須包含初始值設(shè)定項(xiàng):

  • 顯式 extern 聲明
  • 類成員的聲明
  • 類中的聲明
  • 函數(shù)的參數(shù)或函數(shù)的返回類型的聲明

返回局部變量地址時(shí)的注意事項(xiàng)

如果在局部范圍中聲明某個(gè)對(duì)象,則該對(duì)象會(huì)在函數(shù)返回時(shí)銷毀。 如果函數(shù)返回對(duì)該對(duì)象的引用,則當(dāng)調(diào)用方嘗試使用 null 引用時(shí),該引用可能會(huì)在運(yùn)行時(shí)導(dǎo)致訪問(wèn)沖突。

// C4172 means Don't do this!!!
Foo& GetFoo()
{
  Foo f;
  ...
  return f;
} // f is destroyed here

編譯器會(huì)在這種情況下發(fā)出警告:警告 C4172: 返回局部變量或臨時(shí)變量的地址。 在簡(jiǎn)單程序中,如果調(diào)用方在覆蓋內(nèi)存位置之前訪問(wèn)引用,則有時(shí)可能不會(huì)發(fā)生訪問(wèn)沖突。 這純屬運(yùn)氣。 請(qǐng)注意該警告。

對(duì)指針的引用
聲明對(duì)指針的引用的方式與聲明對(duì)對(duì)象的引用差不多。聲明對(duì)指針的引用將生成一個(gè)可像常規(guī)指針一樣使用的可修改值。
以下代碼示例演示了使用指向指針的指針與使用對(duì)指針的引用之間的差異。
函數(shù) Add1 和 Add2 在功能上是等效的(雖然它們的調(diào)用方式不同)。二者的差異在于,Add1 使用雙間接尋址,而 Add2 利用了對(duì)指針的引用的便利性。

// references_to_pointers.cpp
// compile with: /EHsc

#include <iostream>
#include <string>

// STL namespace
using namespace std;

enum {
  sizeOfBuffer = 132
};

// Define a binary tree structure.
struct BTree {
  char *szText;
  BTree *Left;
  BTree *Right;
};

// Define a pointer to the root of the tree.
BTree *btRoot = 0;

int Add1( BTree **Root, char *szToAdd );
int Add2( BTree*& Root, char *szToAdd );
void PrintTree( BTree* btRoot );

int main( int argc, char *argv[] ) {
  // Usage message
  if( argc < 2 ) {
   cerr << "Usage: Refptr [1 | 2]" << "\n";
   cerr << "\nwhere:\n";
   cerr << "1 uses double indirection\n";
   cerr << "2 uses a reference to a pointer.\n";
   cerr << "\nInput is from stdin.\n";
   return 1;
  }

  char *szBuf = new char[sizeOfBuffer];
  if (szBuf == NULL) {
   cerr << "Out of memory!\n";
   return -1;
  }

  // Read a text file from the standard input device and
  // build a binary tree.
  //while( !cin.eof() ) 
  {
   cin.get( szBuf, sizeOfBuffer, '\n' );
   cin.get();

   if ( strlen( szBuf ) ) {
     switch ( *argv[1] ) {
      // Method 1: Use double indirection.
      case '1':
        Add1( &btRoot, szBuf );
        break;
      // Method 2: Use reference to a pointer.
      case '2':
        Add2( btRoot, szBuf );
        break;
      default:
        cerr << "Illegal value '"
         << *argv[1]
         << "' supplied for add method.\n"
           << "Choose 1 or 2.\n";
        return -1;
     }
   }
  }
  // Display the sorted list.
  PrintTree( btRoot );
}

// PrintTree: Display the binary tree in order.
void PrintTree( BTree* MybtRoot ) {
  // Traverse the left branch of the tree recursively.
  if ( btRoot->Left )
   PrintTree( btRoot->Left );

  // Print the current node.
  cout << btRoot->szText << "\n";

  // Traverse the right branch of the tree recursively.
  if ( btRoot->Right )
   PrintTree( btRoot->Right );
}

// Add1: Add a node to the binary tree.
//    Uses double indirection.
int Add1( BTree **Root, char *szToAdd ) {
  if ( (*Root) == 0 ) {
   (*Root) = new BTree;
   (*Root)->Left = 0;
   (*Root)->Right = 0;
   (*Root)->szText = new char[strlen( szToAdd ) + 1];
   strcpy_s((*Root)->szText, (strlen( szToAdd ) + 1), szToAdd );
   return 1;
  }
  else {
   if ( strcmp( (*Root)->szText, szToAdd ) > 0 )
     return Add1( &((*Root)->Left), szToAdd );
   else
     return Add1( &((*Root)->Right), szToAdd );
  }
}

// Add2: Add a node to the binary tree.
//    Uses reference to pointer
int Add2( BTree*& Root, char *szToAdd ) {
  if ( Root == 0 ) {
   Root = new BTree;
   Root->Left = 0;
   Root->Right = 0;
   Root->szText = new char[strlen( szToAdd ) + 1];
   strcpy_s( Root->szText, (strlen( szToAdd ) + 1), szToAdd );
   return 1;
  }
  else {
   if ( strcmp( Root->szText, szToAdd ) > 0 )
     return Add2( Root->Left, szToAdd );
   else
     return Add2( Root->Right, szToAdd );
  }
}

用法:Refptr [1 | 2]

其中:
1 使用雙間接尋址
2 使用對(duì)指針的引用。輸入來(lái)自 stdin。

相關(guān)文章

  • C++實(shí)現(xiàn)LeetCode(65.驗(yàn)證數(shù)字)

    C++實(shí)現(xiàn)LeetCode(65.驗(yàn)證數(shù)字)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(65.驗(yàn)證數(shù)字),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C語(yǔ)言超詳細(xì)講解指針的使用

    C語(yǔ)言超詳細(xì)講解指針的使用

    C語(yǔ)言這門課程在計(jì)算機(jī)的基礎(chǔ)教學(xué)中一直占有比較重要的地位,然而要想突破C語(yǔ)言的學(xué)習(xí),對(duì)指針的掌握是非常重要的,本文將具體針對(duì)指針的基礎(chǔ)做詳盡的介紹
    2022-05-05
  • C語(yǔ)言入門篇--學(xué)習(xí)選擇,if,switch語(yǔ)句以及代碼塊

    C語(yǔ)言入門篇--學(xué)習(xí)選擇,if,switch語(yǔ)句以及代碼塊

    本篇文章是基礎(chǔ)篇,適合c語(yǔ)言剛?cè)腴T的朋友,本文主要帶大家學(xué)習(xí)一下C語(yǔ)言的選擇,if,switch語(yǔ)句及代碼塊,幫助大家快速入門c語(yǔ)言的世界,更好的理解c語(yǔ)言
    2021-08-08
  • C語(yǔ)言中static和auto用法詳解

    C語(yǔ)言中static和auto用法詳解

    大家好,本篇文章主要講的是C語(yǔ)言中static和auto用法詳解,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-01-01
  • 深入解析C語(yǔ)言中的內(nèi)存分配相關(guān)問(wèn)題

    深入解析C語(yǔ)言中的內(nèi)存分配相關(guān)問(wèn)題

    這篇文章主要深入地介紹了C語(yǔ)言中的內(nèi)存分配,C語(yǔ)言編程中的內(nèi)存泄漏問(wèn)題一直以來(lái)都是C編程中的一大棘手問(wèn)題,本文從malloc和指針等方面對(duì)C內(nèi)存進(jìn)行了深層次講解,強(qiáng)烈推薦!需要的朋友可以參考下
    2015-08-08
  • C++設(shè)計(jì)模式之原型模式

    C++設(shè)計(jì)模式之原型模式

    這篇文章主要介紹了C++設(shè)計(jì)模式之原型模式,本文講解了什么是原型模式、為什么要使用原型模式、代碼實(shí)例等內(nèi)容,需要的朋友可以參考下
    2014-09-09
  • C++菱形繼承和虛繼承的實(shí)現(xiàn)

    C++菱形繼承和虛繼承的實(shí)現(xiàn)

    本文主要介紹了C++菱形繼承和虛繼承的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • C語(yǔ)言詳細(xì)圖解浮點(diǎn)型數(shù)據(jù)的存儲(chǔ)實(shí)現(xiàn)

    C語(yǔ)言詳細(xì)圖解浮點(diǎn)型數(shù)據(jù)的存儲(chǔ)實(shí)現(xiàn)

    使用編程語(yǔ)言進(jìn)行編程時(shí),需要用到各種變量來(lái)存儲(chǔ)各種信息。變量保留的是它所存儲(chǔ)的值的內(nèi)存位置。這意味著,當(dāng)您創(chuàng)建一個(gè)變量時(shí),就會(huì)在內(nèi)存中保留一些空間。您可能需要存儲(chǔ)各種數(shù)據(jù)類型的信息,操作系統(tǒng)會(huì)根據(jù)變量的數(shù)據(jù)類型,來(lái)分配內(nèi)存和決定在保留內(nèi)存中存儲(chǔ)什么
    2022-05-05
  • 使用c++調(diào)用windows打印api進(jìn)行打印的示例代碼

    使用c++調(diào)用windows打印api進(jìn)行打印的示例代碼

    這篇文章主要介紹了使用c++調(diào)用windows打印api進(jìn)行打印的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • C++學(xué)習(xí)筆記之類與對(duì)象詳解

    C++學(xué)習(xí)筆記之類與對(duì)象詳解

    這篇文章主要為大家介紹了C++類與對(duì)象,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2021-12-12

最新評(píng)論

历史| 鲁甸县| 礼泉县| 建平县| 北辰区| 湘乡市| 奉贤区| 新津县| 长子县| 同心县| 紫金县| 军事| 云霄县| 大新县| 合水县| 竹北市| 栾城县| 文水县| 虹口区| 原平市| 邵阳县| 惠州市| 潞西市| 宾川县| 淮阳县| 上高县| 岑巩县| 邵阳市| 屯留县| 合川市| 遵化市| 湘阴县| 岫岩| 宜春市| 上高县| 陈巴尔虎旗| 鄂州市| 南郑县| 宣威市| 海兴县| 锡林浩特市|