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

问题描述 投票:0回答:2

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

练习 14.26:为 StrVecString、定义下标运算符 StrBlob 和 StrBlobPtr 类。(P.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
};

编译类

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) 

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

c++ gcc g++ compiler-warnings
2个回答
5
投票

const char operator [](std::size_t n) const {return elements[n];}
这会返回
elements[n]
的 const 副本,这根本没有用。当您不希望调用者更改您的内容时,您会返回一个常量,但由于您在这里返回一个副本,因此无论如何您都不会更改任何内容。

您的第一个示例是返回 const 引用,这是您应该在此处执行的操作。


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];}
© www.soinside.com 2019 - 2024. All rights reserved.