在以下代码中(取自有效的 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;
}
在此代码中,如果将 static_cast 从 const TextBlock& 更改为 const TextBlock,这将导致非 const 版本的 operator[] 被递归调用。谁能解释这背后的原因(为什么 const TextBlock 导致不调用 const 成员函数 operator[] )。
最佳答案
原因是因为
const A a();
和
A b();
是不同的对象,在 CPP 中非常量对象不能调用常量函数,反之亦然;因此,您需要分别为 const 和非常量对象声明两次相同的函数。
cout << a[0] << endl;
是合法的,但是
cout << b[0] << endl;
不是。 因此,您应该为非常量对象重载 [] 运算符。为了避免复制代码,作者建议通过放弃其常量性来为 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 函数的 []operator 返回 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 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]);
这将从这个调用重载运算符 [] 的常量转换对象返回一个非常量引用到 char :) 正是因为这个原因你不能使用
return const_cast <char &> ((*this)[position]);
因为这是一个非常量对象;因此,它将调用非成本函数(重载运算符[]),这将导致无限递归。
希望这是有道理的。
关于c++ - static_cast<const A>(*this) 和 static_cast<const A&>(*this) 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3802556/