2011-10-14 30 views

回答

34

假設你要取成員函數size()的地址,那麼你會這樣寫:

auto address = &demo::size; 

但它可能是很可能是該成員的數據的地址size爲好。模糊的情況。因此,語言規範是不允許的。

這並不是說C++委員會不可能提出解決方案,但我認爲這樣做沒有什麼大的進展。因此,標準只是簡單地禁止它。

typedef void fun_type(); 

struct demo 
{ 
    fun_type size; //It looks like a member-data, but it's a member-function 
}; 

void demo::size() //define the member function 
{ 
    std::cout << "It is crazy!" << std::endl; 
} 

int main() 
{ 
    demo d; 
    d.size(); //call the function! 
} 

輸出:

這是瘋狂的

而且,如果一個聲明的成員函數size()作爲成員的數據和成員函數之間的差別就越區分視覺

見在線演示:http://ideone.com/ZjwyJ

現在,如果我們可以實現成員函數如上所述的話,那就太明顯,甚至到你不能相同名新增其他成員肉眼:

struct demo 
{ 
    fun_type size; 
    int  size; //error - choose a different name for the member! 
}; 

等待這不完全正確,因爲故事尚未完成。有一點不太明顯,我需要在這裏添加。您可以相同名稱添加多個成員:

typedef void fun_type0(); 
typedef void fun_type1(int a); 
typedef void fun_type2(int a, int b); 

struct demo 
{ 
    fun_type0 member; //ok 
    fun_type1 member; //ok 
    fun_type2 member; //ok 
}; 

這是完全有效的代碼,因爲每個成員都是不同類型的功能,這樣你就可以將它們定義爲:

void demo::member() 
{ 
    std::cout << "member()" << std::endl; 
} 
void demo::member(int a) 
{ 
    std::cout << "member(" << a << ")" << std::endl; 
} 
void demo::member(int a, int b) 
{ 
    std::cout << "member(" << a << ", "<< b << ")" << std::endl; 
} 

測試代碼:

int main() 
{ 
    demo d; 
    d.member(); 
    d.member(10); 
    d.member(200,300); 
} 

輸出:

member() 
member(10) 
member(200, 300) 

在線演示:http://ideone.com/OM97Q


結論...

因爲他們的功能,您可以添加成員相同的名稱,只要不同的類型。這是啓用由一個功能成員函數重載(或簡單函數重載)。

1.不幸的是,該語言沒有爲成員數據提供類似的功能,如成員數據重載,語言也不提供跨成員重載(它允許成員數據和成員函數在問題中具有相同的名稱—)。

那麼這裏自然會出現一個問題:難道他們不會導致含糊不清問題?是的,他們這樣做。但需要指出的一點是,C++委員會想出了一個解決這個模糊問題的解決方案,因爲他們看到了巨大的收益(在函數重載的情況下)。

但問題中的案例仍然不明確,因爲委員會沒有提出解決方案,因爲他們沒有看到任何巨大的優勢(如前所述)。此外,當我說:「C++委員會想出瞭解決方案」,我的意思並不是說該解決方案一直標準化,我只是說他們知道編譯器如何能夠解決它,多麼複雜的解決辦法是。

+0

歧義並不是真正的答案。它與'demo :: size'是否是一個重載函數有什麼不同? – tenfour

+1

@tenfour:你完全錯過了這一點。這個模糊性*對於重載函數也是存在的,但關鍵是C++委員會想出了一個解決這個模糊問題的解決方案,因爲他們看到了這樣做的巨大收益。但這個問題在這個問題上仍然不明確,因爲委員會沒有提出解決方案。當我說*「C++委員會提出瞭解決方案」*時,我並不是說該解決方案是標準化的,我僅僅意味着他們知道編譯器如何解決它,以及解決方案有多複雜。 – Nawaz

+0

我明白了,但它似乎與[這個問題]類似(http://stackoverflow.com/questions/4331837/why-cant-functions-be-overloaded-by-return-type)答案似乎是含糊不清,但更具體的原因是委員會希望進行函數調用而不依賴於外部環境。我想知道這個問題是否有類似的更詳細的答案。 (或者這可能是答案?) – tenfour

6

因爲如果你在你的類中使用size那麼編譯器不知道該怎麼做。它可以是int數據成員,也可以是函數指針。因此,編譯器不能單獨既親切

6

爲例(不也許是最好的,但它可能在視覺上解釋):

class Size { 
     std::size_t size_; 
    public: 
     Size(std::size_t s = std::size_t()) : size_(s){} 
     std::size_t operator()() const { 
      return size_; 
     } 
     void operator()(std::size_t s) { 
      size_ = s; 
     }   
}; 

class Demo { 
    public: 
     Size size; 
}; 

int main() { 
    Demo d; 
    d.size(10); 
    std::size_t size = d.size(); 
    return 0; 
} 

基本變量可能是贖回爲好。所以編譯器無法知道你的意圖。 當然這是由語言定義的,它不可能在同一範圍內與標識符具有相同的名稱。

+0

極好的例子。 – UncleZeiv

相關問題