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

Yue*_*ang 1 c++ compiler-construction gcc g++ compiler-warnings

这是C++ Primer第5版的练习:

练习14.26:为StrVec,String,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
};
Run Code Online (Sandbox Code Playgroud)

编译类时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
};
Run Code Online (Sandbox Code Playgroud)

来自编译器的警告:

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

我正在使用的编译器:

gcc version 4.8.1 (Ubuntu 4.8.1-2ubuntu1~13.04) 
Run Code Online (Sandbox Code Playgroud)

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

sim*_*onc 5

第一个版本是返回对数组元素的引用.这是否是const引用确定您是否可以只读取元素的值或写入元素.

第二个版本返回一个数组元素的副本.如果这是故意的,你只需要

char operator [](std::size_t n) const {return elements[n];}
Run Code Online (Sandbox Code Playgroud)

如果你想要两个重载operator [],一个允许读取元素,另一个允许它被写入,你需要返回引用而不是

      char& operator [](std::size_t n)       {return elements[n];}
const char& operator [](std::size_t n) const {return elements[n];}
Run Code Online (Sandbox Code Playgroud)


jre*_*ady 5

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

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

  • @ Alan.W,我们都犯了愚蠢的错误:) (2认同)