加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 同一函数的const和非const版本 – 反模式?

发布时间:2020-12-16 09:59:46 所属栏目:百科 来源:网络整理
导读:最近我检查了大量的遗留C代码,发现了我以前从未见过的生产C代码: class Foo{public: void Bar() { std::cout "Hello from Bar()!" std::endl; } void Bar() const { const_castFoo*(this)-Bar(); }}; 这是一个巨大的反模式吗?我的意思是,函数是const还是非
最近我检查了大量的遗留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();
}

解决方法

不,不总是.

这种模式有合法用途.例如,假设您正在编写集合,并且用于检索元素的代码相当复杂(例如,哈希表).您不希望复制所有代码,但您还希望您的集合能够用作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的,你知道只有当这个对象指向的对象也是非const时才可以调用它.因此,抛弃常数是有效的.

(当然,类似于这种情况,你可以通过抛弃const实例的常量来调用非const方法,但此时它是你的类的用户已经引入了未定义的行为,所以你被覆盖只要你的班级被正确使用.)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读