编译两个相似的类时,为什么编译器输出不同?

时间:2014-01-17 22:45:46

标签: c++ gcc compiler-construction g++ compiler-warnings

以下是 C ++ Primer 5th Edition 的练习:

  

练习14.26:为 StrVec String 定义下标运算符,   StrBlob和StrBlobPtr类。(P.566)

编译的类StrVec没有任何错误或警告.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) 

为什么会这样?两个班级之间有什么显着差异吗?

2 个答案:

答案 0 :(得分: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];}

答案 1 :(得分:5)

const char operator [](std::size_t n) const {return elements[n];} 这将返回elements[n]的const副本,完全没用。当你不希望调用者改变你的东西时你返回一个const,但是因为你在这里返回一个副本,所以你不会改变任何东西。

你的第一个例子是返回一个const引用,这是你应该在这里做的。