1. //重载operator[]并对不同版本给予不同的返回类型;
class TextBlock {
public:
const char& operator[](std::size_t position) const {
return text[position];
}
char& operator[](std::size_t position) {
return text[position];
}
private:
std::string text;
};
void Print(const TextBlock& ctb) {
std::cout << ctb[0];
}
2.
#include <iostream>
// 尝试non-const 中返回类型不是reference to char 而是 char
// 然后尝试 tb[0] = 'x';
class TextBlock {
public:
TextBlock(std::string s) {
text = s;
}
const char& operator[](std::size_t position) const {
return text[position];
}
char operator[](std::size_t position) {
return text[position];
}
private:
std::string text;
};
void test() {
TextBlock tb("Hello");
tb[0] = 'x'; // |error: lvalue required as left operand of assignment|
}
3.
class TextBlock {
public:
char& operator[](std::size_t position) const { // error: invalid initialization of reference of type 'char&' from expression of type 'const char'|
return text[position];
}
private:
std::string text;
};
但是
class TextBlock {
public:
char& operator[](std::size_t position) const {
return text[position];
}
private:
char* text;
};
/*
能通过编译:
原因是第二种情况中 const修饰的对象不能变的成员是 text指针,而不是指针中的内容;*/
4.
class CTextBlock {
public:
CTextBlock(const char* s) {
strcpy(pText, s);
}
char& operator[](std::size_t position) const {
return pText[position];
}
private:
char* pText;
};
void test() {
const CTextBlock cctb("Hello");
char* pc = &cctb[0]; // 因为返回的是 non-const char& 所以可以值赋给指针变量,并且内容可修改
*pc = 'J';
}
5. 使用概念上的常量性
class CTextBlock {
public:
CTextBlock(const char* s) {
strcpy(pText, s);
}
char& operator[](std::size_t position) const {
return pText[position];
}
std::size_t length() const;
private:
char* pText;
mutable std::size_t text_length; //
mutable bool length_is_valid; // mutable 修饰说明其非常量
};
std::size_t CTextBlock::length() const {
if (!length_is_valid) {
text_length = std::strlen(pText);
length_is_valid = true;
}
return text_length;
}
6.在const 和 non-const 成员函数中避免重复
class CTextBlock {
public:
CTextBlock(std::string s) {
text = s;
}
const char& operator[](std::size_t position) const {
return text[position];
}
char& operator[](std::size_t position) {
return
const_cast<char&> (
static_cast<const CTextBlock&>(*this)
[position]
);
}
private:
std::string text;
};