2014-01-17 80 views
1

下面是℃的運動++入門第五版編譯兩個相似的類時,爲什麼編譯器輸出不同?

練習14.26:定義下標運算符爲您StrVec字符串, StrBlob和StrBlobPtr類(P.566)

StrVec編譯沒有任何錯誤,也不warning.Below是類體:

/** 
* @brief The StrVec class a std::vector like class without template 
*   std:string is the only type it holds. 
*/ 
class StrVec 
{ 
public: 
    //! default constructor 
    StrVec(): 
     element(nullptr), first_free(nullptr), cap(nullptr){} 

    // etc  

    //! public members 
      std::string& operator [](std::size_t n)  {return element[n];} 
    const std::string& operator [](std::size_t n) const {return element[n];} 
    //           ^^^^^ 
    // etc  
private:  
    //! data members 
    std::string* element;  // pointer to the first element 
    std::string* first_free; // pointer to the first free element 
    std::string* cap;   // pointer to one past the end 

    std::allocator<std::string> alloc; 
    // etc 
}; 

當編譯類String,產生一個警告,如下所示:

/** 
* @brief std::string like class without template 
* 
*  design: 
* 
*  [0][1][2][3][unconstructed chars][unallocated memory] 
*  ^  ^    ^
*  elements first_free   cap 
*/ 
class String 
{ 
public: 
    //! default constructor 
    String(); 

    // etc 

      char operator [](std::size_t n)  {return elements[n];} 
    const char operator [](std::size_t n) const {return elements[n];} 
    //         ^^^^^ 
private:  
    //! data members 
    char* elements; 
    char* first_free; 
    char* cap; 

    std::allocator<char> alloc;  
    // etc 
}; 

從編譯器警告:

warning: type qualifiers ignored on function return type [-Wignored-qualifiers] 
    const char operator [](std::size_t n) const {return elements[n];} 
             ^

編譯器我用:

gcc version 4.8.1 (Ubuntu 4.8.1-2ubuntu1~13.04) 

這是爲什麼?這兩個班級之間有什麼顯着差異?

+1

在第二個類中,您引用直接數據類型('char')而不是數據引用('std :: string&'),即指針。 – abiessu

回答

5

const char operator [](std::size_t n) const {return elements[n];} 這將返回一個elements[n]的常量副本,根本沒有用。當你不想讓調用者改變你的東西時,你返回一個const,但是因爲你在這裏返回一個副本,所以你不會改變任何東西。

你的第一個例子是返回一個const引用,這是你應該在這裏做的。

+0

爲什麼你會返回一個'const char&'而不是一個'char'?也許把它變成一個'const char *'?我可以看到,但有點奇怪。 – WhozCraig

+0

@WhozCraig:我會這樣做是出於習慣;如果我總是返回'const {DATATYPE}&'那麼我就不用擔心它們之間的區別了...... – abiessu

+0

我想只是爲了與其他'operator []'一致?但是,沒有'char'的任何真正的好處。 – jready

5

第一個版本返回對數組元素的引用。無論這是否是一個const引用,都會決定您是否可以只讀取元素的值或寫入元素。

第二個版本返回一個數組元素的副本。如果這是故意的,你只需要

char operator [](std::size_t n) const {return elements[n];} 

如果你想的operator []兩個重載,一個允許讀取某個元件與另一允許它被寫,您需要返回引用,而不是

 char& operator [](std::size_t n)  {return elements[n];} 
const char& operator [](std::size_t n) const {return elements[n];}