const和非const版本的同一个函数 - 反模式?

时间:2015-10-23 18:34:06

标签: c++ const anti-patterns

最近我检查了大量遗留的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();
}

1 个答案:

答案 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方法,但此时它的已经引入了未定义行为的类的用户,只要您的类被正确使用,就会被覆盖。)