2012-09-03 29 views
1

這裏是一個非常具體的問題!向量(或其他動態容器)內的類變量的C++ const引用

我有一個持有關於一個星球的數據的類。例如,它具有像矢量(double x,double y,double z)來保存其位置的東西,以及一個用於保存其半徑的雙變量。

我經常使用引用來獲取私有變量的「只讀公共訪問」。我調用setter方法來改變私有變量。

但是,我不認爲這是允許在一個動態容器,如矢量或列表。

我已經試過「常數常數」指針,這個想法正在初始化列表初始化一次,他們將不能夠指向任何東西或修改的變量。但編譯時出現相同的錯誤信息。

的消息是這樣的:「錯誤:非靜態const成員const double* const x,不能使用默認的賦值運算符」

因此,有與複製類時,我就做了「的push_back」問題一個矢量 - 對嗎?

下面是一個例子代碼:

class planet{ 

    private: 

     double _radius; 

    public: 

     // Constructor 
     planet() : rad(_radius){ 
      _radius = 0.0f; 
     } 

     // This is a setter method - works fine 
     void setrad(double new_rad){ 
      _radius = rad; 
     } 

     // This is a better solution to the getter method 
     // - does not seem to work with dynamic containers! 
     const double& rad; // This is initialized in the constructor list 
}; 

int main(...){ 

... 

    std::vector<planet> the_planets; 
    planet next_planet_to_push; 
    next_planet_to_push.setrad(1.0f); 

    // This causes the error! 
    the_planets.push_back(next_planet_to_add); 

... 

} 
+0

通過getter方法提供只讀訪問權限時出現了什麼問題?我沒有理由在這裏存儲引用。 – juanchopanza

+0

您需要爲您的Planet類定義一個複製構造函數和賦值操作符。試試星球吧!行星b; a = b; – mythagel

+0

我不確定爲什麼你覺得引用比訪問函數「更好」,但它增加了對象大小和訪問的運行時間成本,並且(如你發現的那樣)阻止該類被簡單地複製。訪問函數應該內聯,在這種情況下,與直接訪問成員相比,不應該有任何開銷。 –

回答

1

您需要提供自己的拷貝構造函數和賦值操作符用於包含成員引用或const成員(在你的情況下,兩個)類。

編譯器生成的將試圖做一個淺拷貝,這在這種情況下是不可能的。

+0

你能指出我在正確的方向如何做到這一點嗎? – user3728501

+0

@EdwardBird肯定。 Google複製構造函數和賦值運算符。 –

+0

好的,謝謝,我會閱讀它! – user3728501

1

std::vector需要operator=爲了工作。默認operator=只是分配每個成員。它不能完成const &

+0

你能指出我如何做到這一點?我應該谷歌什麼?謝謝! – user3728501

+0

@EdwardBird:我會做同樣的事情Kerrek SB建議 - 使用一個簡單的getter – Andrew

+1

@EdwardBird:有一個選項可以使用指針而不是引用,因爲指針可以重新綁定。但它很醜。不要這樣做 - 使用簡單的getter – Andrew

1

確實,std::vector的元素必須是可分配的,因此它們不能包含常量或引用成員。

但是,爲什麼沒有一個簡單的訪問功能

double rad() const { return _radius; } 
+0

答案很簡單,上面的解決方案是很長的類型,它是更直觀的能夠鍵入如果(planet.x> 10)<做某事> ...雖然我認爲這是不好的能夠以這種方式寫入變量 – user3728501

+0

兩個額外的括號太長而不能輸入?那麼,如果必須的話,你可以有一個'std :: reference_wrapper'成員。 –

+0

不,不太長,只是不直觀!我現在將谷歌std :: reference_wrapper。 – user3728501

0

什麼是即使只有使半徑公衆對這一問題?

如果所有的setter確實是this->radius = some_other_radius,代碼沒有提供任何益處:是增加代碼,提供的語言已經提供了值得的特點是什麼?

+0

我不喜歡有公共變量,但我可能只需要在此情況... :( – user3728501

+2

@EdwardBird如果你想只讀公共訪問,那麼這絕對不是解決方案。一個c​​onst訪問器很容易。 – juanchopanza

+0

好吧謝謝,我會去檢查它! – user3728501