首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C++中返回引用的重载const和non类方法

在C++中返回引用的重载const和non类方法
EN

Stack Overflow用户
提问于 2013-06-05 21:13:12
回答 1查看 2.5K关注 0票数 0

我在C++中有一个数据结构类,带有一个对象的访问器(可能很大),而且我有使用这个访问器的const和non方法,所以我需要重载它。我正在寻找下面代码的评论--也许有一种方法可以完成同样更干净的事情?

按照我的理解,在下面的示例中,有两种方法可以实现这一点,而不重复访问器中的代码--方法get()。我不确定这两种方法和中的任何一种方法是否存在严重问题,我想在这里提供一些指导,

我喜欢方法A,因为:

  • 只有一个const_cast
  • 方法get()的const版本返回一个副本
  • 非const方法直接获取非const引用。

我不喜欢方法A,因为:

  • 非const方法get()仅是const,而不是由编译器检查的。
  • 虽然不是不可能,但更难获得参考。

我喜欢方法B,因为:

  • 编译器检查const方法get()的一致性。
  • 返回对象的副本由用户控制。

我不喜欢B方法,因为:

  • 需要两个很难读的const_casts

下面是这两种情况的(最小)示例代码。

代码语言:javascript
复制
/**
 * summary:
 * Two classes with an overloaded method which is
 * guaranteed (by contract) not to change any
 * internal part of the class. However, there is a
 * version of this method that will return a non-const
 * reference to an internal object, allowing the user
 * to modify it. Don't worry about why I would ever
 * want to do this, though if you want a real-world
 * example, think about std::vector<>::front()
 *
 * The difference between A and B can be summarized
 * as follows. In both cases, the second method merely
 * calls the first, wrapped with the needed
 * const_cast's
 *
 * struct A {
 *     int& get();
 *     int  get() const;
 * };
 *
 * struct B {
 *     const int& get() const;
 *           int& get();
 * };
 *
 **/

struct A
{
    int _val;

    A() : _val(7) {};

    // non-const reference returned here
    // by a non-const method
    int& get()
    {
        // maybe lots of calculations that you do not
        // wish to be duplicated in the const version
        // of this method...
        return _val;
    }

    // const version of get() this time returning
    // a copy of the object returned
    int get() const
    {
        // CONST-CAST!!?? SURE.
        return const_cast<A*>(this)->get();
    }

    // example of const method calling the
    // overloaded get() method
    int deep_get() const
    {
        // gets a copy and makes
        // a copy when returned
        // probably optimized away by compiler
        return this->get();
    }
};

struct B
{
    int _val;

    B() : _val(7) {};

    // const reference returned here
    // by a const method
    const int& get() const
    {
        // maybe lots of calculations that you do not
        // wish to be duplicated in the non-const
        // version of this method...
        return _val;
    }

    // non-const version of get() this time returning
    // a copy of the object returned
    int& get()
    {
        // CONST-CAST!? TWO OF THEM!!?? WHY NOT...
        return const_cast<int&>(const_cast<const B*>(this)->get());
    }

    // example of const method calling the
    // overloaded get() method
    int deep_get() const
    {
        // gets reference and makes
        // a copy when returned
        return this->get();
    }
};


int main()
{
    A a;
    a.get() = 8;  // call non-const method
    a.deep_get(); // indirectly call const method

    B b;
    b.get() = 8;  // call non-const method
    b.deep_get(); // indirectly call const method
}
EN

回答 1

Stack Overflow用户

发布于 2013-06-05 21:39:00

成员函数的一致性应根据以下问题来确定:是上下文中用于修改对象?的成员函数(成员直接修改对象,或者返回对内部数据的引用/指针,以便外部调用者可以修改对象)。如果是的话,就把它变成非康斯特,否则就让它成为康斯特。

编译器将正确地选择仅在一致性不同的重载之间进行选择。然而,返回类型并不用于过载解析。此外,还应该根据预期成本和您将要返回的内容的预定所有权来决定按值返回/按引用返回。幸运的是,C++11通过提供move semantics使生活变得更容易。这意味着您可以愉快地按值返回大型数据结构。只有在引用对象将超过外部调用者的情况下,才返回引用。

在我看来,您的int& get()应该重命名为void set(int),您可以将int get() const划分为一个计算助手和一个适当的get()

代码语言:javascript
复制
class C
{
    int val_;
public:
    void modify()   { /* some expensive computation on val_ */ }
    int get() const { return val_; }
    void set(int v) { val_ = v_; }
};

或者,如果您想保持get()函数,您可以这样做

代码语言:javascript
复制
class D
{
int val_;
public:
    void modify()    { /* some expensive computation on val_ */ }
    int get() const  { modify(); return val_; }
    int& get()       { modify(); return val_; } // no const-cast needed
};
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16950003

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档