overloaded const and non-const class methods returning references in C++ I have a data-structure class in C++ with an accessor to some object (may be large) and I have const and non-const methods using this accessor so I need to overload it. I am looking for a critique of the code below - maybe there is a way to accomplish the same thing that is cleaner?

The way I understand it, there are two ways to achieve this without duplicating the code in the accessor in the following case, the method get(). I am not sure if there are serious issues with either of these two methods and I would like some guidance here.

I like method A because:


only one const_cast
const-version of the method get() returns a copy
the non-const method gets the non-const reference directly


I don't like method A because:


the non-const method get() is const only by contract, (not checked by compiler)
harder to get a const-reference, though not impossible


I like method B because:


the const-ness of the const method get() is checked by compiler
copy of the returned object is controlled by the user


I don't like method B because:


requires two const_casts which is hard to read


here is the (minimal) example code of the two cases.

/**
 * 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&lt;&gt;::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&amp; get();
 *     int  get() const;
 * };
 *
 * struct B {
 *     const int&amp; get() const;
 *           int&amp; get();
 * };
 *
 **/

struct A
{
    int _val;

    A() : _val(7) {};

    // non-const reference returned here
    // by a non-const method
    int&amp; 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&lt;A*&gt;(this)-&gt;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-&gt;get();
    }
};

struct B
{
    int _val;

    B() : _val(7) {};

    // const reference returned here
    // by a const method
    const int&amp; 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&amp; get()
    {
        // CONST-CAST!? TWO OF THEM!!?? WHY NOT...
        return const_cast&lt;int&amp;&gt;(const_cast&lt;const B*&gt;(this)-&gt;get());
    }

    // example of const method calling the
    // overloaded get() method
    int deep_get() const
    {
        // gets reference and makes
        // a copy when returned
        return this-&gt;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
}
const-version of the method get() returns a copy


Why is this a good thing?


  the non-const method get() is const only by contract, (not checked by compiler)
      harder to get a const-reference, though not impossible


What?


  the const-ness of the const method get() is checked by compiler
      copy of the returned object is controlled by the user


What does it matter if it is const if you have to go to the effort of making a copy.


  requires two const_casts which is hard to read


Really!

PS. getters and setters are an anti pattern (unless you are a container).
Exposing the internal implementation like this tightly couples your class to any code that uses it. This makes modifying your code in the future much harder. It is best to make your methods do the work rather than expose the members and do the work outside the class.

class X
{
     Y   value;

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


OK so you want the code to get the value in one location:

class Z
{
     Y   value;

     public:
         Y&amp;       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&amp; from this function it is
         // fine and you don't need to add const-ness back anyway.
         Y const&amp; get() const {return const_cast&lt;Z&amp;&gt;(*this).get();}
 };