2012-09-13 128 views
3

假設我們有下面的代碼:引用問題傳遞const對象

#include <iostream> 

class Person{ 
public: 
    Person(int age); 
    int get_a(); 
private: 
    int a; 
}; 

Person::Person(int age) 
{ 
    a = age; 
} 

int Person::get_a() 
{ 
    return a; 
} 

void Show_Age(Person P) 
{ 
    std::cout<<P.get_a()<<std::endl; 
} 

int main() { 

    Person P(10); 
    Show_Age(P); 
    return 0; 
} 

現在假設我們有一個沉重的物體,我們應該通過引用傳遞的人,所以我們繼續:

void Show_Age(Person &P) 
{ 
    std::cout<<P.get_a()<<std::endl; 
} 

有不是一個問題,但一個好的觀察是P應該是const,我們試試吧:

void Show_Age(const Person &P) 
{ 
    std::cout<<P.get_a()<<std::endl; 
} 

編譯失敗:

error: passing ‘const Person’ as ‘this’ argument of ‘int Person::get_a()’ discards qualifiers [-fpermissive] 

如何解決?

+0

爲什麼不做個'Show_Age'一個成員函數? – jrok

+0

因爲它是一個測試功能,實際上我有另一個類,並使用獲得的功能函數,所以類中我有一個向量,所以我需要通過引用傳遞一個對象 – FacundoGFlores

回答

12

你應該標記,以便get_aconst此編譯:

class Person{ 
public: 
    Person(int age); 
    int get_a() const; 
private: 
    int a; 
}; 

int Person::get_a() const 
{ 
    return a; 
} 

否則告訴的成員函數不修改對象的狀態,編譯器,使其兼容const指針和引用。

1

你必須標記Person::get_a爲常數,以及:

class Person 
{ 
    // ... 

    int get_a() const; 

    // ... 
}; 

這告訴get_a不修改對象的編譯器。

1

Const正確性是病毒性的,你應該從內部開始(即每個類應該標記不修改對象的成員函數爲const,允許調用者在const對象上使用它們(或對const對象)。

+0

謝謝,這是一個很好的建議。讓我看看,你是建議我:我應該得到重載的get函數,以允許類的用戶正確使用類作爲他們希望如何? – FacundoGFlores

+1

@facunvd:稍微多一點一般意義上,我們不是在談論重載,而是每個功能。一個不修改對象狀態的函數應該是'const'(它是** const,但你應該這樣標記它)。添加'const'關鍵字意味着編譯器和你一樣知道:'get_a'不會修改對象。沒有它,編譯器不知道它,並且不允許你在const對象上調用該函數。 –