1. 程式人生 > >使用const關鍵字進行函式過載

使用const關鍵字進行函式過載

通常地,不同的過載函式不能具有相同數目的引數和引數型別。函式的返回值型別,雖然屬於成員函式的signature的組成部分,但僅僅返回值型別不同,是不能構成函式過載的,因為這會造成redefinition的錯誤。

但有一個例外,就是使用const關鍵字進行函式過載,是成員函式成為const函式。見下面的程式碼:

// Overloading Based on const

#include <iostream>

#include <string>

using namespace std;

class AClass

{

public:

AClass():greetingwords("Hello, world!"

)

{

}

string greeting()// (1)

{

return greetingwords + " - from nonconst version.";

}

//const string greeting()// (2)

//{

//return greetingwords + " - from right const version.";

//}

//string greeting() const// (3)

//{

//return greetingwords + " - from right const version.";

//}

const string greeting() const// (4)

{

return

greetingwords + " - from const - const version.";

}

private:

const string greetingwords;

};

int main(void)

{

AClass a_class;

const AClass b_class;

cout << a_class.greeting() << endl;

cout << b_class.greeting() << endl;

return 0;

}

說明:

a.(1)(4)中的greeting的引數數目和型別都是完全一致的(兩個函式都沒有引數

),按照通常的說法,這會出現編譯錯誤,但事實上,上面的程式可以正常執行。因此,(1)(4)中的兩個greeting函式,並無redefinition的問題,這是因為(4)中的greeting函式名稱後有一個const關鍵字的緣故;

b.同樣道理,如果將這個(4)定義的greeting註釋掉,使用(3)中的greeting函式的定義,結果也是正確的,因為(3)中的greeting函式名稱後也有一個const關鍵字;

c.(3)(4)不能同時出現,否則會出現redefinition的編譯錯誤。因為它們之間的不同僅是返回值型別不同,一個是string,另一個是const string,而僅僅是返回值型別的不同,編譯器是無法區分兩個過載函式的不同;

d.基於上面的道理,(1)(2)也不能同時出現;

e.結論。如果兩個函式的引數數目和資料型別都是一樣的,只要將其中一個改為const成員函式(即,函式名稱和引數後又const關鍵字),則仍然可以構成有效的函式過載;

f.輸出。上面的程式碼輸出:

Hello, world! – from nonconst version.

Hello, world! – from const – const version.

a_class是一個nonconst物件,因此選擇了(1)中的greeting定義;b_class是一個const物件,因此選擇了(4)中的greeting定義。