1. 程式人生 > >C++中的const用法【02】----函式的引數和返回值

C++中的const用法【02】----函式的引數和返回值

如果按值傳遞物件,它意味著傳遞的引數在函式中是不能被修改的。

如果按常量返回使用者定義型別的物件的值,這意味著返回值不能被修改。

如果傳遞引數並返回地址,const 將保證改地址不會被改變。

1.傳遞const  值

如果引數是按值傳遞,那麼可用const 修飾指定引數。

void fun1(int value1 , const int value2) {
        value1 ++ ; // Safe
        value2 ++ ; // Error ,被const 修飾的變數不能被更改
}

這裡有一個規定,就是value2已被const 修飾,在fun1()函式的整個生命週期中,value2都無法被修改。由於採用的是按值傳遞,因此fun1()在這裡會定義2個實參的副本作為形參,並將第二個形參設定為const 物件。

const 在函式中的用法很簡單,就是將一個物件修飾成“無法被修改的”,因此可以將它試做被調的工具而非主調的。(因為上述過程對於主調來說是不知情的)

為了使得程式更加清晰,最好將const 限定引數放在函內部而非它的引數列表,這樣可以使得被調的形參列表與主調相同。

#include <iostream>
using namespace std ;

void fun(int value1) {
        const int& i = value1 ;
        i ++ ;          //Error,i is a const object;
<span style="white-space:pre">	</span>value ++ ;      
}

int main (void) {
        int a = 1 , b = 2 ;
        fun(a) ;
        return 0 ;
}
我們可以藉助引用,讓const 限定引數這一過程在函式內部實現,但需要注意的是,在內部實現的情況下,我們定義的引用變數是const 的,但形參依然是非const ,這意味著形參依舊可以被改變。因此,我們一旦使用了引用去實現,在接下來的描述中,要儘量使用const 修飾的引用變數而非原引數。

2.返回const 值

對函式的返回值而言,const 也有類似的功能:將一個函式的返回值限定為常量。

其宣告形式如下:

const int fun() ;
這樣的形式會使得函式框架中原變數不會修改。
#include <iostream>
using namespace std ;

int fun3() {
        return 1 ;
}

int fun4() {
        return 2 ;
}

int main (void) {
        const int i = fun3() ;  //It is safe ;
        int j = fun4() ;        //It is also safe ;
        return 0 ;
}

對於內建型別(int , double , char等)而言,按值返回的物件是否是一個const ,都無關緊要,因為它返回的是僅僅一個值,就如同 
const int i = 0 ;
int j = i ;
一樣,是一個簡單的賦值過程,因此對於主調的接收值型別來說,有沒有const 都可以。但在沒有必要時最好不要帶上,不然容易引起混淆。

而當處理使用者自定義的型別(struct,class)時,按值返回常量卻是非常重要的,如果一個函式按值返回一個類型別的const 物件時,那麼這個函式的返回值就不能作為一個左值(即不能出現在等號左邊,不能被賦值或被修改)

#include <iostream>
using namespace std ;

class Example {
private:
        int i_ ;
public:
        Example(int i) : i_(i) {}
        void modify() {
                i_ ++ ;
        }
        // default constructor
        ///~
        // copy constructor
        ///~
};

Example fun1() {
        return Example() ;
}

const Example fun2() {
        return Example() ;
}

int main(void) {
        fun1() = Example(1) ;   //safe
        fun1().modify() ;       //safe
        fun2() = Example(1) ;   //error , fun2的返回值型別是const Example , 即返回的物件不能被改變
        fun2().modify() ;       //error , const物件不能呼叫非const成員函式
        return 0 ;
}


<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"><span style="white-space:pre">	</span>fun1()返回一個非const 物件,而fun2()返回一個const 物件,只有非const返回值能作為一個左值引用。當按值返回一個類物件時,如果不希望這個類物件被改變,就請大家使用const 來修飾。</span>
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">
</span>
總結:在按值傳遞內建型別時,const 沒有意義的原因是,編譯器已經成功的阻止它成為左值,因為這樣的函式返回的是一個值,而不是一個變數,一個值只能被其他物件接收,而不能被更改。因此,只有按值返回一個使用者定義的類型別時,const 的修飾才會變得不可或缺。

3.傳遞和返回地址

如果傳遞或返回一個地址,那麼其處置可能被通過操縱地址所改變,使用const 修飾可以有效的阻止這類事情的發生。並且,無論什麼時候將地址傳遞給函式,都英愛儘可能的使用const 去限制。

#include <iostream>
using namespace std ;

void fun1(int *) {}

void fun2(const int * cip) {
        * cip = 2 ;             //error,const int * 是限制指標所指向的值不能被改變,因此無法賦值
        int i = * cip ;         
        int * cp2 = cip ;       //error,不能將const int * 賦值給int * ;
}

const char * fun3() {
        return "result of fun3()" ;
}

const int * const fun4() {
        static int i ;
        return &i ;
}

int main(void) {
        int x = 0 ;
        int * ip = &x ;
        const int * cip = &x ;      
        fun1(ip) ;                      
        fun1(cip) ;                     
        fun2(ip) ;                              //!!error,不能用int * 賦值給const int *
        fun2(cip) ;                     
        char * cp = fun3() ;                    //!!error,不能用const char * 賦值給char *
        const char * ccp = fun3() ;     
        int * ip2 = fun4() ;                    //!!error,不能用const int * const 賦值給int *
        const int * const ccip = fun4() ;       
        const int * cip2 = fun4() ;            <span style="color:#ff0000;"> //特別強調,這個是正確的,可以將const int * const 賦給const int * ;
        //因為const int * const 和 const int *都表示指標的指向被const修飾不能隨意改變,這回與函式來說已經足夠了
        //它指向的值是不是const編譯器都不會再去判斷,因為接下來執行的是賦值過程
        //就像我們剛才說的,對於按值傳遞的內建型別的返回值常量有無const修飾都沒有太大區別</span>
        *fun4() = 1 ;                           //!!error,返回的指標本身和它所指向的物件都無法更改,因此不能作為左值
        return 0 ;
}


相關推薦

C++const用法02----函式引數返回

如果按值傳遞物件,它意味著傳遞的引數在函式中是不能被修改的。 如果按常量返回使用者定義型別的物件的值,這意味著返回值不能被修改。 如果傳遞引數並返回地址,const 將保證改地址不會被改變。 1.傳遞const  值 如果引數是按值傳遞,那麼可用const 修飾指定引數。

C++函式引數返回

形式引數和實際引數 在呼叫函式時,大多數情況下,函式是帶引數的。主調函式和被呼叫函式之間有資料傳遞關係。前面已提到:在定義函式時函式名後面括號中的變數名稱為形式引數(formal parameter,簡稱形參),在主調函式中呼叫一個函式時,函式名後面括號中的引數(可以是一個表示式)稱為實際引數(actual

C++引用(作為函式引數返回

一、引用簡介 引用就是某一變數(目標)的一個別名,對引用的操作與對變數直接操作完全一樣。 引用的宣告方法:型別識別符號 &引用名=目標變數名; eg:int a; int &b=

Python_從零開始學習_(32) 函式引數返回

目錄   1.  函式引數和返回值的作用  2.  函式的返回值 進階 3.  函式的引數 進階 1.  函式引數和返回值的作用 函式根據 有沒有引數 以及 有沒有返回值 , 可以 相互相合,  一共有

Python函式引數返回

- 函式引數和返回值的作用 函式:封裝功能獨立的程式碼,在需要時通過函式名被呼叫 引數:外界希望在函式內部處理的資料 返回值:函式完成工作後,給呼叫者的一個結果 函式根據有無引數和返回值,可以相互結合,共有4種組合形式 1.無引數,無返回值 2.無引數,有返回值 3.有引數,無返回值

JNI實現回撥| JNI呼叫JAVA函式|引數返回的格式

程式碼下載:http://dl.dbank.com/c0c0xs3b24 一、JNI實現回撥 通過JNI在Native層呼叫Java層的方法,來實現Native層向JAVA層傳遞訊息。 JNICallback.java publicclass JNICallback e

在IDEA設定方法自動註釋(帶引數返回

第一部分 設定 開啟設定面板    新建 線上模板 新建自動新增規則,注意 這裡觸發的字元 不能隨便寫 必須為 *   Template text 區域 看上去有點亂,但是是為了顯示時的對齊,該區域的內容如下(空格之類的不要亂動): *

c/c++const用法總結

沒有 pan 分配 值類型 變量初始化 _id 多少 部分 參數 1、修飾常量時:   const int temp1; //temp1為常量,不可變   int const temp2; //temp2為常量,不可變 2、修飾指針時:   主要看const在*的前後,

C#const用法詳解

htm 鏈接 服務器 span img body 用法詳解 -s 設計 本文實例講述了C#中const用法。分享給大家供大家參考。具體用法分析如下: const是一個c語言的關鍵字,它限定一個變量不允許被改變。使用const在一定程度上可以提高程序的安全性和可靠性,另外,

C++CONST用法總結

1、修飾常量時: ? 1 2 const int temp1; //temp1為常量,不可變 int const temp2; //temp2為常量,不可變 2、修飾指標時:   主要看const在*的前後,

C++const用法淺析

看到const 關鍵字,很多程式設計師想到的可能是const 常量,這可有點象踩到陷井上還不知道自己危險了。讀讀以下文字會使你對c++中的const有一個全面的認識。 const 是C++中常用的型別修飾符,有某些微妙的應用場合,如果沒有搞清本源,則錯誤在所難免。本篇中

python 資料型別返回資料型別的函式

字串+字串 →稱為 "拼接"   數字+數字 →稱為"加法運算" 一、資料型別:整型、浮點型、布林型別 1、整型:整數 注意:python2中長整型需要在後面加l,python3中不區分整型和長整

C++陣列作為函式引數返回

C++中陣列作為函式引數或者返回值 概述 在程式設計任務中,經常會遇到將陣列作為函式引數或者返回值,比如在前一篇的計數排序任務中,需要額外的空間來儲存排序後的元素,並且將該陣列返回給主函式。本文會介紹幾種可行的方案,僅供參考。 陣

c# 繫結combox,同時獲取valuestext

public void BindCombox(ComboBox cb, string id, string text,string str) //id 為value,text為text,str為得到資料集的語句 { DataTable dt = new DataTable()

C語言入門之函式引數返回

什麼是函式的引數?什麼是函式的返回值?它們倆的作用又是什麼呢?估計很多初學者是一頭霧水。  說得簡單一點,若是我們把函式比喻成一臺機器,那麼引數就是原材料,返回值就是最終產品。函式的作用就是根據不同的引數產生不同的返回值。   ◎函式的引數   在函式定義中出現的引

python --函式引數返回

函式引數和返回值的作用 函式根據 有沒有引數以及有沒有返回值,可以相互結合,一共有四種組合形式 1.無引數,無返回值 2.無引數,有返回值 3.有引數,無返回值 4.有引數,有返回值 函式:封裝功能獨立的程式碼,在需要時通過函式名被呼叫,可以直接訪問全域性變數。 返回值

將電影檔案排序—函式作為引數返回,理解js提供的sort氣泡排序

要點: 1.理解函式作為引數和作為返回值,就是將函式的處理結果直接使用了,而沒有進行用第三個變數進行接收而已。 2.js提供的sort氣泡排序演算法是不穩定的,需要加一步比較兩個物件的操作,同時想要進行降序排序只要將返回的值改變一下,即可改變升降排序,不需要重寫。 程式碼: <

物件作為引數返回 複製(拷貝)建構函式

先看一道搜狗的校園招聘題:  不考慮任何編譯器優化(如:NRVO),下述程式碼的第10行會發生 #include <stdio.h>//1 class B//2 {//3 };//4 B func(const B& rhs){//5 return r

一種比較好的JNI JavaC++相互傳遞引數返回的方法

序言 以前在Android上做移動多媒體開發的時候,有很多需要在Java和C++相互傳遞引數的Case,以前因為時間卡的緊,一直沒有去修復這一類的問題,因為能用,沒有出什麼問題,也就沒有想什麼優化方案。最近自己有一些閒暇時間折騰點小玩意兒,也需要從Java和C++之間相互傳遞引數。想

python3 方法各種引數返回

# -*- coding:utf-8 -*- # Author: Evan Mi # 函式 def func1(): print('in the func1') return 0 # 過程 def func2(): print('in th