RX_*_*_RX 4 c++ anti-patterns const
最近我检查了大量遗留的C++代码,发现了我以前从未见过的生产C++代码:
class Foo
{
public:
void Bar()
{
std::cout << "Hello from Bar()!" << std::endl;
}
void Bar() const
{
const_cast<Foo*>(this)->Bar();
}
};
Run Code Online (Sandbox Code Playgroud)
这是一个巨大的反模式吗?我的意思是,函数是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();
}
Run Code Online (Sandbox Code Playgroud)
不,不总是.
这种模式有合法用途.例如,假设您正在编写集合,并且用于检索元素的代码相当复杂(例如,哈希表).您不希望复制所有代码,但您还希望您的集合能够用作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)
);
}
};
Run Code Online (Sandbox Code Playgroud)
在这里,这const_cast<>不是一个谎言.由于你的函数是非函数const,你知道只有当指向的对象this也是非const时才能调用它.因此,抛弃常数是有效的.
(当然,类似于这种情况,你可以const通过抛弃实例的const-ness 来调用非方法const,但是在那时它是你的类的用户已经引入了未定义的行为,所以你只要覆盖你的班级正确使用.)