2014-01-17 82 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];}