在以下代码中(取自有效的C):
class A
{
....
char& operator[](std::size_t position) // now just calls const op[]
{
return
const_cast<char&>( // cast away const on op[]'s return type;
static_cast<const TextBlock&>(*this) // add const to *this's type;
[position] // call const version of op[]
);
}
const char& operator[](int index) const
{
...
}
}
//complete example, tested with VC 2010
#include<iostream>
#include<string>
class TextBlock
{
public:
TextBlock(std::string st):text(st){};
TextBlock(char* cstr): text(cstr){};
TextBlock(const TextBlock& r)
{
std::cout<<"copy constructor called"<<std::endl;
}
char& operator[](int index)
{
std::cout<<"non-const operator"<<std::endl;
return const_cast<char&>(static_cast<const TextBlock>(*this)[index]);
}
const char& operator[](int index) const
{
std::cout<<"const operator"<<std::endl;
return text[index];
}
private:
std::string text;
};
int main()
{
TextBlock rt("hello");
std::cout<<rt[0]<<std::endl;
}
在此代码中,如果您从const TextBlock&更改static_cast;对于const TextBlock,这会导致operator []的非const版本被递归调用.任何人都可以解释这背后的原因是什么(为什么const TextBlock导致不调用const成员函数operator []). 解决方法: 原因是因为
const A a();
和
A b();
是不同的对象,并且在CPP非常量对象中不能调用常量函数,反之亦然;因此,您需要为const和非const对象分别声明两次相同的函数.
cout << a[0] << endl;
是合法的,但是
cout << b[0] << endl;
不是. 因此,您应该为非const对象重载[]运算符.为了避免复制代码,作者建议通过抛弃其constness来使用const对象的函数.出于这个原因,你得到:
char& operator[](std::size_t position)
{
return const_cast <char &>( static_cast <const A &>(*this) [position] );
}
换句话说,您只需将对象转换为const
char& operator[](std::size_t position)
{
const A temp = *this; //create a const object
//and assign current object to it
....
}
尝试使用const obj的[]运算符
char& operator[](std::size_t position)
{
const A temp = *this; //create a const object
//and assign current object to it
return temp[position]; // call an overloaded operator []
// of the const function
}
得到一个错误,因为const函数的[]运算符返回const char&并且此函数返回char& ;.因此施放常数
char& operator[](std::size_t position)
{
const A temp = *this; //create a const object
//and assign current object to it
return const_cast <char &>( temp[position] );
}
现在你完成了.问题是:“如何
const A temp = *this;
return const_cast <char &> (temp[position]);
成了这个:
return const_cast <char &> ( static_cast <const A &> (*this)[position]);
?原因是当你使用temp时 – 你正在对const对象进行非const的隐式转换,因此你可以替换:
const A temp = *this; // implicit cast
同
const A temp = static_cast <const A &> (*this) //explicit
这也有效:
const A temp = const_cast <const A &> (*this)
因为你可以做一个明确的演员 – 你不再需要一个临时演员,因此:
return const_cast <char &> (static_cast <const A &>(*this)[position]);
这将从这个const-casted对象返回一个非const引用,该对象调用一个重载的运算符[] :)正是因为这个原因你不能使用
return const_cast <char &> ((*this)[position]);
因为这是一个非const对象;因此,它将调用非成本函数(重载operator []),这将导致无限递归.
希望它有意义. 来源:https://www./content-4-415151.html
|