[ACCEPTED]-Call a non-const member function from a const member function-constants

Accepted answer
Score: 34
return (const_cast<Foo*>(this))->Second();

Then cry, quietly.

0

Score: 11

It is possible:

const int& First() const 
{ 
    return const_cast<Foo*>(this)->Second(); 
}

int& Second() { return m_bar; }

I wouldn't recommend this; it's ugly 8 and dangerous (any use of const_cast is dangerous).

It's 7 better to move as much common functionality 6 as you can into helper functions, then have 5 your const and non-const member functions 4 each do as little work as they need to.

In 3 the case of a simple accessor like this, it's 2 just as easy to return m_bar; from both of the functions 1 as it is to call one function from the other.

Score: 3

By the definition of const, a function should 6 not modify the state of an object. But if 5 it calls another non-const member, the object's 4 state might get changed, so it's disallowed.

I 3 know you said you didn't want to hear about 2 this, but I think it's important for others 1 that happen upon the question.

Score: 3

The restriction of const member methods 9 are came from compile time. If you can fool 8 the compiler, then yes.

class CFoo
{ 
public:
    CFoo() {m_Foo = this;}
    void tee();

    void bar() const 
    { 
        m_Foo->m_val++;  // fine 
        m_Foo->tee();    // fine
    }
private:
   CFoo * m_Foo;
   int    m_Val;  

};

This actually abolishes 7 the purpose of const member function, so 6 it is better not to do it when design a 5 new class. It is no harm to know that there 4 is a way to do it,especially it can be used 3 as an work-around on these old class that 2 was not well designed on the concept of 1 const member function.

Score: 2

Overload on const:

const int& Second() const
{
    return m_bar;
}

You can add this method and 1 keep the original non-const version.

Score: 1

iterators are similar in this and make an 20 interesting study.

const iterators are often 19 the base for 'non const' iterators, and 18 you will often find const_cast<>() or C style casts used 17 to discard const from the base class with 16 accessors in the child.

Edit: Comment was

I 15 have a zip iterator where the const one 14 inherits from the non-const

This would generally 13 be the wrong inheritence structure (if your 12 saying what I think you are), the reason 11 being that children should not be less restrictive 10 than parents.

say you had some algorithm 9 taking your zip iterator, would it be appropriate 8 to pass a const iterator to a non const 7 ?

if you had a const container, could only 6 ask it for a const iterator, but then the 5 const iterator is derived from an iterator 4 so you just use the features on the parent 3 to have non const access.

Here is a quick 2 outline of suggested inheritence following 1 the traditional stl model

class ConstIterator: 
    public std::_Bidit< myType, int, const myType *, const mType & >
{
  reference operator*() const { return m_p; }
}

class Iterator : public ConstIterator 
{
  typedef ConstIterator _Mybase;
  // overide the types provided by ConstIterator
  typedef myType * pointer;
  typedef myType & reference;

  reference operator*() const
  { 
    return ((reference)**(_Mybase *)this);
  }
}

typedef std::reverse_iterator<ConstIterator> ConstReverseIterator;
typedef std::reverse_iterator<Iterator> ReverseIterator;
Score: 0

I found myself trying to call a non-const 10 member function that was inherited, but 9 was actually const because of the API I 8 was using. Finally I settled on a different 7 solution: re-negotiate the API so that the 6 function I inherit is properly const.

It 5 won't always be possible to negotiate changes 4 to others' functions, but doing so when 3 possible seems cleaner and nicer than needing 2 to use const_cast and it benefits other 1 users as well.

More Related questions