Virtual function question

B

BCC

Hi,

If I have a base class with a virtual function defined:
class CBase {
virtual void Foo();
};

void CBase::Foo()
{
// base class functionality
}

and a derived class which overrides the base class Foo():
class CDerived: public CBase {
void Foo();
};

CDerived::Foo()
{
// derived functionality
}

If I had a pointer to an object of type CDerived, how can I call the base
classes version of Foo() rather than the polymorphic version?
CDerived derived;
CDerived* p_derived = &derived;
p_derived->Foo(); // Want to somehow be able to call base class Foo()!

I think there is a simple way to do this, but I can't find it.

Thanks,
B
 
J

JKop

BCC posted:
Hi,

If I have a base class with a virtual function defined:
class CBase {
virtual void Foo();
};

void CBase::Foo()
{
// base class functionality
}

and a derived class which overrides the base class Foo():
class CDerived: public CBase {
void Foo();
};

CDerived::Foo()
{
// derived functionality
}

If I had a pointer to an object of type CDerived, how can I call the base
classes version of Foo() rather than the polymorphic version?
CDerived derived;
CDerived* p_derived = &derived;
p_derived->Foo(); // Want to somehow be able to call base class Foo()!


p_derived->CBase::Foo();


-JKop
 
X

Xenos

BCC said:
Hi,

If I have a base class with a virtual function defined:
class CBase {
virtual void Foo();
};

void CBase::Foo()
{
// base class functionality
}

and a derived class which overrides the base class Foo():
class CDerived: public CBase {
void Foo();
};

CDerived::Foo()
{
// derived functionality
}

If I had a pointer to an object of type CDerived, how can I call the base
classes version of Foo() rather than the polymorphic version?
CDerived derived;
CDerived* p_derived = &derived;
p_derived->Foo(); // Want to somehow be able to call base class Foo()!

I think there is a simple way to do this, but I can't find it.

Thanks,
B

Are you sure you want to do something like that? You have an object of a
derived class that defines its own behavior and you want to force it to use
its parent's behavior? I think you may have a design problem. You are
trying to tell an object that's own behavior is incorrect.

DrX
 
C

Chris Theis

BCC said:
Hi,

If I have a base class with a virtual function defined:
class CBase {
virtual void Foo();
};

void CBase::Foo()
{
// base class functionality
}

and a derived class which overrides the base class Foo():
class CDerived: public CBase {
void Foo();
};

CDerived::Foo()
{
// derived functionality
}

If I had a pointer to an object of type CDerived, how can I call the base
classes version of Foo() rather than the polymorphic version?
CDerived derived;
CDerived* p_derived = &derived;
p_derived->Foo(); // Want to somehow be able to call base class Foo()!

I think there is a simple way to do this, but I can't find it.

Thanks,
B

What you can do (and what makes sense) is the following:

class CBase {
public:

virtual void Foo() {
... //base class behavior
}
};

class CDerived : public CBase {
public:
void Foo() {
::Foo(); // call base class version
... // extend base class behavior
}
};
 
H

Howard

Chris Theis said:
What you can do (and what makes sense) is the following:

class CBase {
public:

virtual void Foo() {
... //base class behavior
}
};

class CDerived : public CBase {
public:
void Foo() {
::Foo(); // call base class version
... // extend base class behavior
}
};

But that wasn't the question. He asked how to call the base class
implementation "rather than" the derived class implementation. (For some
unkown reason! Sounds like bad design to me.)

-Howard
 
C

Chris Theis

Xenos said:
Are you sure you want to do something like that? You have an object of a
derived class that defines its own behavior and you want to force it to use
its parent's behavior? I think you may have a design problem. You are
trying to tell an object that's own behavior is incorrect.

DrX

This is not necessarily a design problem as there are situation where this
makes perfectly sense. Think of nested serialization for example. Let´s say
you´ve got one object which represents a geometric primitive, whatever that
might be. The Write() function of this object stores the position matrix and
so on, whereas the derived classes (box, sphere, ....) first call the base
version of Write() in their overloaded function and then store the
additional information.

Regards
Chris
 
J

JKop

Chris Theis posted:
class CDerived : public CBase {
public:
void Foo() {
::Foo(); // call base class version
... // extend base class behavior
}
};


I like that!

Is there any problem with the

::Foo();

though?


:: refers to the global namespace, does it not? And so how does

::Foo();

become

CBase::Foo(); ?


And what happens when there's a global function called Foo? Will it not call
the global function?


-JKop
 
J

JKop

Chris Theis posted:
What you can do (and what makes sense) is the following:

class CBase {
public:

virtual void Foo() {
... //base class behavior
}
};

class CDerived : public CBase {
public:
void Foo() {
::Foo(); // call base class version
... // extend base class behavior
}
};


Actually having thought about that, I don't see why that isn't actually the
default behaviour! ie. that over-ridden functions call the base class(es)
functions before doing its own thing!


-JKop
 
H

Howard

Actually having thought about that, I don't see why that isn't actually the
default behaviour! ie. that over-ridden functions call the base class(es)
functions before doing its own thing!

Why in the world should it? The base class may not even *have* any behavior
associated with it (it could be a pure virtual function), let alone the
behavior you want! The developer of a derived class should be completely
free to use, extend, or ignore the base class behavior for any given virtual
function. And even if you *do* want to call the base class function,
there's no guarantee that you want to call it *first*. You might want to
call it between some other code, or at the end of the overriding function.

-Howard
 
H

Howard

Chris Theis said:
class CDerived : public CBase {
public:
void Foo() {
::Foo(); // call base class version
... // extend base class behavior
}
};

As JKop metnioned, doesn't this call the Foo function in the global
namespace? I think you need to specify CBase::Foo() here, don't you?
(After all, what if you have a whole inheritance tree here? You need a way
to dinstiguish *which* base class to call.)

-Howard
 
H

Howard

Chris Theis said:
This is not necessarily a design problem as there are situation where this
makes perfectly sense. Think of nested serialization for example. Let4s say
you4ve got one object which represents a geometric primitive, whatever that
might be. The Write() function of this object stores the position matrix and
so on, whereas the derived classes (box, sphere, ....) first call the base
version of Write() in their overloaded function and then store the
additional information.
Again, that's not the OP's question. It was asked how to call the base
class function "rather than" the derived class function. Not how to call
one from the other.

-Howard
 
X

Xenos

This is not necessarily a design problem as there are situation where this
makes perfectly sense. Think of nested serialization for example. Let´s say
you´ve got one object which represents a geometric primitive, whatever that
might be. The Write() function of this object stores the position matrix and
so on, whereas the derived classes (box, sphere, ....) first call the base
version of Write() in their overloaded function and then store the
additional information.

Regards
Chris
No, that's different that what was asked. The OP asking about forcing a
call to the base-class functionality from outside the object, even though
the derived case had overrridden it. You are talking about the derived
class's member calling the base class version and then adding its own. That
is much different and perfectly fine.

DrX
 
B

Buster

Howard said:
As JKop metnioned, doesn't this call the Foo function in the global
namespace? I think you need to specify CBase::Foo() here, don't you?
(After all, what if you have a whole inheritance tree here? You need a way
to dinstiguish *which* base class to call.)

I remember something (from D&E I think) about a proposal to add
"inherited" as a keyword, and have something like { inherited::Foo (); }
as a syntax for this. The reason this was rejected is that member
typedefs enable it to be simulated, as for example

class derived : public base
{
public:
typedef base inherited;
virtual void foo () { inherited::foo (); }
};

The point being that if "::Foo ()" were the syntax for calling an
inherited version of a virtual function, that discussion would never
have happened. It's no substitute for a quote from the standard, but I'd
say that demonstrates there is no such syntax.

Plus, it's easy to check that it doesn't work, on this system at least:

$ g++ -dumpversion
3.3.1

$ cat inher.cpp
struct base { virtual void foo () { } };
struct derived : public base { void foo () { ::foo (); } };

$ g++ -c inher.cpp
inher.cpp: In member function `virtual void derived::foo()':
inher.cpp:2: error: `::foo' undeclared (first use here)

$
 
C

Chris Theis

JKop said:
Chris Theis posted:



I like that!

Is there any problem with the

::Foo();

though?


:: refers to the global namespace, does it not? And so how does

::Foo();

become

CBase::Foo(); ?


And what happens when there's a global function called Foo? Will it not call
the global function?

Ooops, there was a mistake in my code - I should get some more sleep before
posting ;-)
The correct way would be of course

class CDerived : public CBase {
public:
void Foo() {
CBase::Foo(); // call base class version
... // extend base class behavior
}
};

Sorry & thanks for the question!

Cheers
Chris
 
C

Chris Theis

JKop said:
Chris Theis posted:



Actually having thought about that, I don't see why that isn't actually the
default behaviour! ie. that over-ridden functions call the base class(es)
functions before doing its own thing!

Making it the default behavior would rule out (or at least make it more
diffícult) to implement completely new behavior of derived classes. The
approach of "co-using" the base class code makes sense for IO but for
example think of a function that calculates the volume of primitives.

Cheers
Chris
 
C

Chris Theis

[SNIP]
Plus, it's easy to check that it doesn't work, on this system at least:

$ g++ -dumpversion
3.3.1

$ cat inher.cpp
struct base { virtual void foo () { } };
struct derived : public base { void foo () { ::foo (); } };

$ g++ -c inher.cpp
inher.cpp: In member function `virtual void derived::foo()':
inher.cpp:2: error: `::foo' undeclared (first use here)

And it shouldn´t work on any system! It was simply a mistake on my side
(another case of typing blindly ;-)). The correction of course would be:

struct derived : public base { void foo () { base::foo (); } };

Cheers
Chris
 
C

Chris Theis

[SNIP]
No, that's different that what was asked. The OP asking about forcing a
call to the base-class functionality from outside the object, even though
the derived case had overrridden it. You are talking about the derived
class's member calling the base class version and then adding its own. That
is much different and perfectly fine.

DrX

Being an optimist I wasn´t so sure whether the OP really wanted to enforce
calling the base-class from outside the object, which is of course screwed
;-)

Chris
 

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,968
Messages
2,570,149
Members
46,695
Latest member
StanleyDri

Latest Threads

Top