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

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

Code Review用户
提问于 2013-06-05 21:39:59
回答 1查看 4.9K关注 0票数 2

我在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

Code Review用户

回答已采纳

发布于 2013-06-08 06:45:48

方法get()的const版本返回一个副本

为什么这是件好事?

非const方法get()仅按合同进行,(而不是由编译器检查)更难获得const引用,尽管不是不可能的。

什么?

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

如果是康斯特的话,如果你必须努力复制一份,那又有什么关系呢?

需要两个很难读的const_casts

真的!

PS。getters和setter是反模式(除非您是容器)。

像这样公开内部实现将您的类与使用它的任何代码紧密结合在一起。这使得将来修改代码变得更加困难。最好是让您的方法完成工作,而不是公开成员,并在类之外进行工作。

代码语言:javascript
复制
class X
{
     Y   value;

     public:
         // Why over complicate things.
         // This has the same functionality.
         Y&       get()       {return value;}
         Y const& get() const {return value;}
 };

好的,所以您希望代码在一个位置获得值:

代码语言:javascript
复制
class Z
{
     Y   value;

     public:
         Y&       get()       {return value;}


         // Only really need one cast.
         // We know that get() is not modifying the object.
         // If it was you can't share functions anyway.
         // Thus it is safe to cast away const-ness before calling get.
         // Because you are returning a const& from this function it is
         // fine and you don't need to add const-ness back anyway.
         Y const& get() const {return const_cast<Z&>(*this).get();}
 };
票数 7
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/27064

复制
相关文章

相似问题

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