Overriding const member function with non-const

Discussion in 'C++' started by David Scarlett, Feb 7, 2006.

  1. Hi all,
    I've got a question regarding overriding const member functions with
    non-const functions.

    Let's say I've got a base class defined as follows:

    /*******************/
    class Foo
    {
    public:
    Foo();
    virtual ~Foo();

    virtual void Run() const;
    virtual void DoSomething();
    }
    /*******************/

    Now, what I want to do is create another class derived from it, and
    override the Run() method. However, I will need to call DoSomething()
    from this new version of Run(), even though Run() is const and
    DoSomething() is not. I'm not concerned about whether I should be
    modifying a const object, because the only non-const behaviour
    DoSomething() exhibits is logging related.

    So here are two ways I can think of doing it. Both compile under
    Microsoft VC++6, but I'm still wondering whether the first method in
    particular is ISO C++ compatible (as I wasn't expecting it to
    compile)...

    /*******************/
    class Bar1 : public Foo
    {
    public:
    Bar1();
    virtual ~Bar1();

    // Overriding const Run() with non-const method.
    virtual void Run() {DoSomething();}
    virtual void DoSomething();
    }

    class Bar2 : public Foo
    {
    public:
    Bar2();
    virtual ~Bar2();

    virtual void Run() const {const_cast<Bar2*>(this)->DoSomething();}
    virtual void DoSomething();
    }
    /*******************/

    So do these follow Standard C++, and what are people's opinions on
    which is the better way to do it?

    Thanks.


    --
    David Scarlett

    dscarlett@_ _ _ _ _ _ _ _
    _ _ _ _ _ optusnet.com.au
     
    David Scarlett, Feb 7, 2006
    #1
    1. Advertising

  2. David Scarlett

    Ben Pope Guest

    David Scarlett wrote:
    > Hi all,
    > I've got a question regarding overriding const member functions with
    > non-const functions.
    >
    > Let's say I've got a base class defined as follows:
    >
    > /*******************/
    > class Foo
    > {
    > public:
    > Foo();
    > virtual ~Foo();
    >
    > virtual void Run() const;
    > virtual void DoSomething();
    > }
    > /*******************/
    >
    > Now, what I want to do is create another class derived from it, and
    > override the Run() method. However, I will need to call DoSomething()
    > from this new version of Run(), even though Run() is const and
    > DoSomething() is not. I'm not concerned about whether I should be
    > modifying a const object, because the only non-const behaviour
    > DoSomething() exhibits is logging related.


    So make DoSomething const as well, and make whatever it changes to be
    mutable.

    > So here are two ways I can think of doing it. Both compile under
    > Microsoft VC++6, but I'm still wondering whether the first method in
    > particular is ISO C++ compatible (as I wasn't expecting it to
    > compile)...
    >
    > /*******************/
    > class Bar1 : public Foo
    > {
    > public:
    > Bar1();
    > virtual ~Bar1();
    >
    > // Overriding const Run() with non-const method.
    > virtual void Run() {DoSomething();}
    > virtual void DoSomething();
    > }


    I don't think that would work if you're dealing with a base pointer.

    > class Bar2 : public Foo
    > {
    > public:
    > Bar2();
    > virtual ~Bar2();
    >
    > virtual void Run() const {const_cast<Bar2*>(this)->DoSomething();}
    > virtual void DoSomething();
    > }
    > /*******************/


    I'm not sure that would result in defined behaviour.

    > So do these follow Standard C++, and what are people's opinions on
    > which is the better way to do it?


    See above about mutable, that way you're not lying about the constness
    to the compiler or the user. (maybe you're misleading the user a little)

    Ben Pope
    --
    I'm not just a number. To many, I'm known as a string...
     
    Ben Pope, Feb 7, 2006
    #2
    1. Advertising

  3. David Scarlett

    Rolf Magnus Guest

    David Scarlett wrote:

    > Hi all,
    > I've got a question regarding overriding const member functions with
    > non-const functions.


    That's not possible.

    > Let's say I've got a base class defined as follows:
    >
    > /*******************/
    > class Foo
    > {
    > public:
    > Foo();
    > virtual ~Foo();
    >
    > virtual void Run() const;
    > virtual void DoSomething();
    > }
    > /*******************/
    >
    > Now, what I want to do is create another class derived from it, and
    > override the Run() method. However, I will need to call DoSomething()
    > from this new version of Run(), even though Run() is const and
    > DoSomething() is not. I'm not concerned about whether I should be
    > modifying a const object, because the only non-const behaviour
    > DoSomething() exhibits is logging related.
    >
    > So here are two ways I can think of doing it. Both compile under
    > Microsoft VC++6, but I'm still wondering whether the first method in
    > particular is ISO C++ compatible (as I wasn't expecting it to
    > compile)...
    >
    > /*******************/
    > class Bar1 : public Foo
    > {
    > public:
    > Bar1();
    > virtual ~Bar1();
    >
    > // Overriding const Run() with non-const method.
    > virtual void Run() {DoSomething();}
    > virtual void DoSomething();
    > }


    Are you sure that this overrides the base class Run? This would be quite a
    severe error. But then, VC++6 isn't really famous for its standard
    compliance.

    > class Bar2 : public Foo
    > {
    > public:
    > Bar2();
    > virtual ~Bar2();
    >
    > virtual void Run() const {const_cast<Bar2*>(this)->DoSomething();}
    > virtual void DoSomething();
    > }
    > /*******************/
    >
    > So do these follow Standard C++, and what are people's opinions on
    > which is the better way to do it?


    That depends. You shouldn't look so much at what actually modifies data and
    what doesn't. Take a step backwards and look at the "logical constness".
    From the user's (of the class) point of view, does DoSomething() change the
    object or not? If it does, it should stay non-const. However, then Run()
    potentially changes it too, so it should be non-const as well.
    If DoSomething() doesn't change the external appearance of the object, make
    it const. If it needs to change some caching or logging data within the
    object, make that data mutable.
     
    Rolf Magnus, Feb 7, 2006
    #3
  4. David Scarlett

    mlimber Guest

    David Scarlett wrote:
    > Hi all,
    > I've got a question regarding overriding const member functions with
    > non-const functions.
    >
    > Let's say I've got a base class defined as follows:
    >
    > /*******************/
    > class Foo
    > {
    > public:
    > Foo();
    > virtual ~Foo();
    >
    > virtual void Run() const;
    > virtual void DoSomething();
    > }
    > /*******************/
    >
    > Now, what I want to do is create another class derived from it, and
    > override the Run() method. However, I will need to call DoSomething()
    > from this new version of Run(), even though Run() is const and
    > DoSomething() is not. I'm not concerned about whether I should be
    > modifying a const object, because the only non-const behaviour
    > DoSomething() exhibits is logging related.
    >
    > So here are two ways I can think of doing it. Both compile under
    > Microsoft VC++6, but I'm still wondering whether the first method in
    > particular is ISO C++ compatible (as I wasn't expecting it to
    > compile)...
    >
    > /*******************/
    > class Bar1 : public Foo
    > {
    > public:
    > Bar1();
    > virtual ~Bar1();
    >
    > // Overriding const Run() with non-const method.
    > virtual void Run() {DoSomething();}
    > virtual void DoSomething();
    > }
    >
    > class Bar2 : public Foo
    > {
    > public:
    > Bar2();
    > virtual ~Bar2();
    >
    > virtual void Run() const {const_cast<Bar2*>(this)->DoSomething();}
    > virtual void DoSomething();
    > }
    > /*******************/
    >
    > So do these follow Standard C++, and what are people's opinions on
    > which is the better way to do it?
    >
    > Thanks.
    >
    >
    > --
    > David Scarlett
    >
    > dscarlett@_ _ _ _ _ _ _ _
    > _ _ _ _ _ optusnet.com.au


    See this FAQ:

    http://www.parashift.com/c -faq-lite/const-correctness.html#faq-18.13

    Cheers! --M
     
    mlimber, Feb 7, 2006
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. slide_o_mix
    Replies:
    0
    Views:
    445
    slide_o_mix
    Oct 15, 2003
  2. Alex
    Replies:
    0
    Views:
    412
  3. fungus
    Replies:
    13
    Views:
    948
    fungus
    Oct 31, 2008
  4. Markus Keppeler
    Replies:
    13
    Views:
    959
    Stuart Redmann
    Jul 29, 2011
  5. ittium
    Replies:
    5
    Views:
    462
    88888 Dihedral
    Jan 12, 2012
Loading...

Share This Page