为了账号安全,请及时绑定邮箱和手机立即绑定

复制,常量和非常量,吸气剂的优雅解决方案?

复制,常量和非常量,吸气剂的优雅解决方案?

C++
慕尼黑的夜晚无繁华 2019-08-30 17:21:52
你有没有恨它class Foobar {public:    Something& getSomething(int index) {        // big, non-trivial chunk of code...        return something;    }    const Something& getSomething(int index) const {        // big, non-trivial chunk of code...        return something;    }}我们无法使用另一个方法实现这两种方法,因为您无法const从const版本中调用非版本(编译器错误)。演员将被要求const从非const一个版本调用该版本。有没有一个真正优雅的解决方案,如果没有,最接近一个?
查看完整描述

3 回答

?
慕容森

TA贡献1853条经验 获得超18个赞

我从其中一本Effective C ++书籍中回忆一下,这样做的方法是通过从另一个函数中抛弃const来实现非const版本。


它不是特别漂亮,但它是安全的。由于调用它的成员函数是非const的,因此对象本身是非const的,并且允许抛弃const。


class Foo

{

public:

    const int& get() const

    {

        //non-trivial work

        return foo;

    }


    int& get()

    {

        return const_cast<int&>(const_cast<const Foo*>(this)->get());

    }

};


查看完整回答
反对 回复 2019-08-30
?
子衿沉夜

TA贡献1828条经验 获得超3个赞

怎么样:


template<typename IN, typename OUT>

OUT BigChunk(IN self, int index) {

    // big, non-trivial chunk of code...

    return something;

}


struct FooBar {

    Something &getSomething(int index) {

        return BigChunk<FooBar*, Something&>(this,index);

    }


    const Something &getSomething(int index) const {

        return BigChunk<const FooBar*, const Something&>(this,index);

    }

};

显然你仍然会有目标代码重复,但没有源代码重复。与const_cast方法不同,编译器将检查两种版本方法的const正确性。


您可能需要将BigChunk的两个有趣实例声明为类的朋友。这是一个很好用的朋友,因为朋友的功能隐藏在靠近朋友的地方,所以不存在无约束耦合的风险(哦!)。但我现在不会尝试这样做的语法。随意添加。


有可能BigChunk需要尊重自己,在这种情况下,上面的定义顺序不会很好地工作,并且需要一些前向声明来解决它。


此外,为了避免在标题中找到BigChunk并决定实例化并调用它,即使它在道德上是私有的,你可以将整个批次移动到FooBar的cpp文件中。在匿名命名空间中。内部联系。还有一个标语“小心豹子”。


查看完整回答
反对 回复 2019-08-30
?
绝地无双

TA贡献1946条经验 获得超4个赞

尝试通过重构代码来消除getter。如果只有极少数其他东西需要Something,请使用友元函数或类。


通常,Getters和Setter打破封装,因为数据暴露给世界。使用friend只会将数据公开给少数几个,因此可以提供更好的封装。


当然,这并不总是可能的,所以你可能会被吸气剂困住。至少,大多数或所有“非平凡的代码块”应该在一个或多个私有函数中,由两个getter调用。


查看完整回答
反对 回复 2019-08-30
  • 3 回答
  • 0 关注
  • 468 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信