以下是 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)
为什么会这样?两个班级之间有什么显着差异吗?
答案 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引用,这是你应该在这里做的。