Overriding const member function with non-const

D

David Scarlett

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.
 
B

Ben Pope

David said:
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
 
R

Rolf Magnus

David said:
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.
 
M

mlimber

David said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top