2014-10-19 27 views
3

我正在爲Vector3和Quaternion編寫類。 這裏是我的代碼:使用C++的「const」關鍵字的建議

// .h file 
Quaternion operator * (const Vector3& v) const; 

// .cpp file 
Quaternion Quaternion::operator * (const Vector3& v) const 
{ 
    float s = -(m_v.dot(v)); 
    Vector3 vt = (v*m_s) + m_v.cross(v); 
    return Quaternion(s, vt.getX(), vt.getY(), vt.getZ()); 
} 

我的錯誤與「回報」行,因爲我裏面Vector3.h這樣宣稱:

float& getX(); 
float& getY(); 
float& getZ(); 

我想通了,我可以通過聲明喜歡這裏通過這個案例:

const float& getX() const; 
const float& getY() const; 
const float& getZ() const; 

我也看到了,我不會用這個了:

Vector3 v(1.0f, 2.0f, 3.0f); 
v.getX()++; 
// or v.getX() += 1; => coz I feel writing code like this is more readable. 

而且必須這樣寫代碼:

float x = v.getX(); // I dont like this coz it will waste memory 
        // if it's not an "float" but a big object 
x += 1; 
v.setX(x); 

所以,我的問題:

  1. 有什麼辦法來滿足這兩種情況下,或者,簡單地說,就是一個權衡選擇?
  2. C++程序員經常使用「const」關鍵字是一個好習慣嗎?
+5

1.提供'const'和non-'const'重載。是的。但是,如果你的getter和setters返回數據引用,那麼你可能會公開數據成員。 – juanchopanza 2014-10-19 12:32:55

+1

你可以只返回float而不是float&或const float&。該方法本身應該是const的,否則你不能將它用於非const對象。你寫「如果不是浮動但是一個大對象,我不喜歡這個」 - 但它是_is_浮動的。 – gnasher729 2014-10-19 12:35:31

+0

給juanchopanza和gnasher729:謝謝你的提示。 – Khoa 2014-10-19 14:39:22

回答

4

你可以做的是提供兩個不同版本的函數。

class Vector { 
    public: 
     float getX() const; 
     float & getX(); 
}; 

void foo(const Vector & const_v, Vector & v) { 
    v.getX() += 1; 
    const_v.getX() += 1; // Won't work. 
} 

注意,如果您Vector僅僅是數據的容器,它更簡單,只需要聲明它struct並允許所有成員的直接訪問。只有當訪問私有字段的機會應該受到某種程度的限制時(例如,您希望Vector經常被標準化,所以任何寫入字段的應用程序都應該將其全部更改爲非常具體的方式)。

-1

在get函數中使用const是一種很好的編程習慣,因爲get函數應該只有權限讀取數據,而不是修改數據。

+0

你能解釋爲什麼我downvoted? – 2014-10-19 13:31:46

+0

嗨!我是這個問題的主人。我沒有投下你的答案。我希望你知道我很欣賞你的答案。謝謝。我也希望你能很快得到你的答案。 (因爲我想要它,也是:D) – Khoa 2014-10-19 14:23:49

1

首先,在一般情況下,如果可能的話,您應該標記爲const。這樣做可以爲您節省大量調試或稍後閱讀文檔,因爲編譯器可以幫助診斷邏輯問題。

對於返回對私有成員的引用,C++標準庫使用具有兩個重複版本的方法,一個聲明爲const,另一個不是。這也可以是你的方法。

但在您的具體情況下,您可以將這些公開。很多書告訴你總是將成員聲明爲private,並使用getter和setter,因爲這就是「OOP的工作原理」,但事實並非如此。如果一個類只保存數據並且不提供其他抽象,那麼通過將這些字段設爲私有就沒有任何好處。

最後,如果您非常關心效率,那麼只要您實際上不需要float&,就應該返回float。後者還需要存儲器或寄存器分配,可能大於普通的存儲器所佔用的存儲器容量。訪問float&也需要間接,這是相當昂貴的。

+0

感謝您的提示。我完全不知道這些知識。你能告訴我哪個文件或關鍵字找到它嗎?我真的要更多地瞭解它。謝謝。 – Khoa 2014-10-19 14:28:52

+0

「這個知識」=>我的意思是你寫的最後一段。 :) – Khoa 2014-10-19 15:33:21

+0

@ user3550678:這只是基本的知識。我懷疑你會找到一個專門討論它的網頁或博客文章。 – 2014-10-19 15:53:51