为什么编译器在编译两个相似的类时输出不同? 下面是C++入门第五版的练习:

为什么编译器在编译两个相似的类时输出不同? 下面是C++入门第五版的练习:,c++,gcc,compiler-construction,g++,compiler-warnings,C++,Gcc,Compiler Construction,G++,Compiler Warnings,练习14.26:为字符串定义下标运算符, StrBlob和StrBlobPtr类。(第566页) 类StrVec编译时没有任何错误或警告。下面是类主体: /** * @brief The StrVec class a std::vector like class without template * std:string is the only type it holds. */ class StrVec { public: //! default cons

练习14.26:为字符串定义下标运算符, StrBlob和StrBlobPtr类。(第566页)

StrVec
编译时没有任何错误或警告。下面是类主体:

/**
 * @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
};
来自编译器的警告:

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) 

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

第一个版本返回对数组元素的引用。这是否是常量引用决定了您是否可以读取元素的值,或者也可以写入元素

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

char operator [](std::size_t n) const {return elements[n];}
如果需要两个重载的
运算符[]
,一个允许读取元素,另一个允许写入元素,则需要返回引用

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

第一个版本返回对数组元素的引用。这是否是常量引用决定了您是否可以读取元素的值,或者也可以写入元素

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

char operator [](std::size_t n) const {return elements[n];}
如果需要两个重载的
运算符[]
,一个允许读取元素,另一个允许写入元素,则需要返回引用

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

const char操作符[](std::size_t n)const{return elements[n];}
这将返回
元素[n]
的常量副本,这根本没有用。当你不想让打电话的人改变你的东西时,你返回一个常量,但是既然你在这里返回一个副本,你无论如何也不会改变任何东西


您的第一个示例是返回一个常量引用,这是您应该在这里执行的操作。

常量字符操作符[](std::size\t n)const{return elements[n];}
这将返回
元素[n]
的常量副本,这根本没有用。当你不想让打电话的人改变你的东西时,你返回一个常量,但是既然你在这里返回一个副本,你无论如何也不会改变任何东西


您的第一个示例是返回常量引用,这是您应该在这里执行的操作。

在第二个类中,您引用的是直接数据类型(
char
),而不是数据引用(
std::string&
),即指针。在第二个类中,您引用的是直接数据类型(
char
)而不是数据引用(
std::string&
),即指针。为什么要返回
常量字符&
,而不仅仅是
字符
?把它变成一个
常量字符*
也许?我看得出来,但是有点。。。奇怪。@WhozCraig:我会这样做是出于习惯;如果我总是返回
const{DATATYPE}&
,那么我就不必担心差异……我想只是为了与其他
操作符[]
保持一致?但是,是的,
char
@residentcookie没有任何真正的好处。是的,我能收集到的唯一好处是以后通过指针使用所述引用来寻址(
const
)元素,这将与
const char&
,而不是
char
rvalue一起工作。@residentcookie从来没有写过更真实的单词。我每天都制作它们(或者有时看起来是这样)。为什么要返回一个
常量字符&
,而不仅仅是一个
字符
?把它变成一个
常量字符*
也许?我看得出来,但是有点。。。奇怪。@WhozCraig:我会这样做是出于习惯;如果我总是返回
const{DATATYPE}&
,那么我就不必担心差异……我想只是为了与其他
操作符[]
保持一致?但是,是的,
char
@residentcookie没有任何真正的好处。是的,我能收集到的唯一好处是以后通过指针使用所述引用来寻址(
const
)元素,这将与
const char&
,而不是
char
rvalue一起工作。@residentcookie从来没有写过更真实的单词。我每天都做(有时看起来是这样)。