最近我检查了大量遗留的C ++代码,发现了我以前从未见过的生产C ++代码:
class Foo
{
public:
void Bar()
{
std::cout << "Hello from Bar()!" << std::endl;
}
void Bar() const
{
const_cast<Foo*>(this)->Bar();
}
};
这是一个巨大的反模式吗?我的意思是,函数是const还是非const,提供两个版本的重点是什么?这是某种'const-correctness cheat',允许调用const函数是这样的情况:
void InvokeBar(const Foo& foo)
{
// oh boy! I really need to invoke a non-const function on a const reference!
foo.Bar();
}
答案 0 :(得分:7)
不,不是总是。
此模式有合法用途。例如,假设您正在编写集合,并且用于检索元素的代码相当复杂(例如,哈希表)。您不想复制所有代码,但您也希望您的集合能够用作const和非const。
所以,你可能会这样做:
struct HashTable {
...
const Value &get(Key key) const {
... complex code for retrieving the key
}
Value &get(Key key) {
return const_cast<Value &>(
static_cast<const HashTable *>(this)->get(key)
);
}
};
在这里,const_cast<>
并不是一个谎言。由于你的函数是非const
,你知道只有当this
指向的对象也是非const时才能调用它。因此,抛弃常数是有效的。
(当然,与此情况类似,您可以通过丢弃const
实例的const
来调用非const
方法,但此时它的已经引入了未定义行为的类的用户,只要您的类被正确使用,就会被覆盖。)