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

你有没有恨它


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一个版本调用该版本。


有没有一个真正优雅的解决方案,如果没有,最接近一个?


慕尼黑的夜晚无繁华
浏览 469回答 3
3回答

慕容森

我从其中一本Effective C ++书籍中回忆一下,这样做的方法是通过从另一个函数中抛弃const来实现非const版本。它不是特别漂亮,但它是安全的。由于调用它的成员函数是非const的,因此对象本身是非const的,并且允许抛弃const。class Foo{public:&nbsp; &nbsp; const int& get() const&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; //non-trivial work&nbsp; &nbsp; &nbsp; &nbsp; return foo;&nbsp; &nbsp; }&nbsp; &nbsp; int& get()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return const_cast<int&>(const_cast<const Foo*>(this)->get());&nbsp; &nbsp; }};

子衿沉夜

怎么样:template<typename IN, typename OUT>OUT BigChunk(IN self, int index) {&nbsp; &nbsp; // big, non-trivial chunk of code...&nbsp; &nbsp; return something;}struct FooBar {&nbsp; &nbsp; Something &getSomething(int index) {&nbsp; &nbsp; &nbsp; &nbsp; return BigChunk<FooBar*, Something&>(this,index);&nbsp; &nbsp; }&nbsp; &nbsp; const Something &getSomething(int index) const {&nbsp; &nbsp; &nbsp; &nbsp; return BigChunk<const FooBar*, const Something&>(this,index);&nbsp; &nbsp; }};显然你仍然会有目标代码重复,但没有源代码重复。与const_cast方法不同,编译器将检查两种版本方法的const正确性。您可能需要将BigChunk的两个有趣实例声明为类的朋友。这是一个很好用的朋友,因为朋友的功能隐藏在靠近朋友的地方,所以不存在无约束耦合的风险(哦!)。但我现在不会尝试这样做的语法。随意添加。有可能BigChunk需要尊重自己,在这种情况下,上面的定义顺序不会很好地工作,并且需要一些前向声明来解决它。此外,为了避免在标题中找到BigChunk并决定实例化并调用它,即使它在道德上是私有的,你可以将整个批次移动到FooBar的cpp文件中。在匿名命名空间中。内部联系。还有一个标语“小心豹子”。

绝地无双

尝试通过重构代码来消除getter。如果只有极少数其他东西需要Something,请使用友元函数或类。通常,Getters和Setter打破封装,因为数据暴露给世界。使用friend只会将数据公开给少数几个,因此可以提供更好的封装。当然,这并不总是可能的,所以你可能会被吸气剂困住。至少,大多数或所有“非平凡的代码块”应该在一个或多个私有函数中,由两个getter调用。
打开App,查看更多内容
随时随地看视频慕课网APP