Determine if a function has been overridden

S

S. I. Becker

Is it possible to determine if a function has been overridden by an
object, when I have a pointer to that object as it's base class (which
is abstract)? The reason I want to do this is that I want to call this
function if it has been overridden, and not if it hasn't, e.g

class CBase
{
public:
virtual long mightBeOverridden(int i) { return 0; } // not a pure
virtual function, since sub-classes should not have to define it
bool isFunctionOverRidden() { return false; }// This is what I want
to code
virtual int id()=0; // this class is an abstract class because of
this function - I don't think that this is relevant but more info is good
};

class CDerived1
{
// Does not override the function
int id() { return 1; }
};

class Derived2
{
long mightBeOverridden(int i) { return i; }
// Should not have to also override isAboveFunctionOverRidden()
int id() { return 2; }
};

class Derived3
{
long mightBeOverridden(int i) { return i * i; }
// Should not have to also override isAboveFunctionOverRidden()
int id() { return 3; }
};

int foo(CBase* pObj, int i, int j)
{
if(pObj)
{
if(pObj->isFunctionOverridden())
return mightBeOverridden(i);
}

return j;
}


I googled on this and came up with nought, as did a search of this list.
I'm guessing that means it's impossible. I thought that I might
compare function pointers ( return mightBeOverridden !=
CBase::mightBeOverridden ) but that doesn't distinguish between the two.

If it's relevant, I'm using MS Visual C++ 7.0 (aka .NET 2002), due to
upgrade to 8.0 soon.

Thanks in advance,

Stewart
 
S

S. I. Becker

Sorry, in my example the Derived classes should be declared as follows.

CDerived1 : public Base

CDerived2 : public Base

CDerived3 : public Base

The problem remains.
 
V

Victor Bazarov

S. I. Becker said:
Is it possible to determine if a function has been overridden by an
object, when I have a pointer to that object as it's base class (which
is abstract)? The reason I want to do this is that I want to call
this function if it has been overridden, and not if it hasn't, e.g

This seems like an attempt to work around a bad design. Why in the
world would you intentionally design your system like that?
class CBase
{
public:
virtual long mightBeOverridden(int i) { return 0; } // not a pure
virtual function, since sub-classes should not have to define it
bool isFunctionOverRidden() { return false; }// This is what I want
to code
virtual int id()=0; // this class is an abstract class because of
this function - I don't think that this is relevant but more info is
good };

class CDerived1
{
// Does not override the function
int id() { return 1; }
};

class Derived2
{
long mightBeOverridden(int i) { return i; }
// Should not have to also override isAboveFunctionOverRidden()
int id() { return 2; }
};

class Derived3
{
long mightBeOverridden(int i) { return i * i; }
// Should not have to also override isAboveFunctionOverRidden()
int id() { return 3; }
};

int foo(CBase* pObj, int i, int j)
{
if(pObj)
{
if(pObj->isFunctionOverridden())
return mightBeOverridden(i);

You mean

return pObj->mightBeOverridden(i);
}

return j;
}


I googled on this and came up with nought, as did a search of this
list. I'm guessing that means it's impossible. I thought that I
might compare function pointers ( return mightBeOverridden !=
CBase::mightBeOverridden ) but that doesn't distinguish between the
two.

I don't think it's possible without some trick with dynamic_cast which
means that 'foo' has to know about derived classes, which in turn shows
that the design is bad, which suggests that you need to revisit the
design instead of patching it up like that.

The whole point of virtual functions is that they are supposed to be
used *without* any regard to whether the derived class has or hasn't
overridden them. If suddenly you have an urge to learn that, then
you probably shoudn't have those functions virtual in the first place.
If it's relevant, I'm using MS Visual C++ 7.0 (aka .NET 2002), due to
upgrade to 8.0 soon.

It's not.

V
 
P

Patrick

Agree this will be a bad design, but however if you want to do this,
I haven't try but just simply by theory

class base
{
public:
virtual void overrideFunc() {}
virtual int isFunctionOveride()
{
base refObj;
return (&this->overrideFunc != &refObj.overrideFunc );
}
};

class derive1 : public base
{
public:
virtual void overrideFunc() { /* overrided */ }
};
 
S

S. I. Becker

Victor said:
This seems like an attempt to work around a bad design. Why in the
world would you intentionally design your system like that?

I thought I might get a response like this!

The situation is like that in foo. There is a value that should be
obtained, only if the object has code for how to do it, otherwise
another should be used. Following your comments, I have decided to
change it as follows:

int CBase::mightBeOverridden(int i, int j) // Note, this function now
takes in two arguments
{
i; // avoid compiler warning - will be optimised out
return j;
}

int CDerived2::mightBeOverridden(int i, int j)
{
j; // avoid compiler warning - will be optimised out
return i;
}

int CDerived3::mightBeOverridden(int i, int j)
{
j; // avoid compiler warning - will be optimised out
return i * i;
}

int foo(CBase* pObj, int i, int j)
{
if(pObj)
{
return pObj->mightBeOverridden(i, j);
}

return j;
}

Comments appreciated.

Stewart
 
M

Marcus Kwok

S. I. Becker said:
The situation is like that in foo. There is a value that should be
obtained, only if the object has code for how to do it, otherwise
another should be used. Following your comments, I have decided to
change it as follows:

int CBase::mightBeOverridden(int i, int j) // Note, this function now
takes in two arguments
{
i; // avoid compiler warning - will be optimised out
return j;
}

Instead of putting in a statement that doesn't really do anything ("i;")
to avoid the compiler warning, I would just comment out the unused
parameters:

int CBase::mightBeOverriddent(int /*i*/, int j)
{
return j;
}

and similarly for the rest.
 
E

Earl Purple

Patrick said:
Agree this will be a bad design, but however if you want to do this,
I haven't try but just simply by theory

class base
{
public:
virtual void overrideFunc() {}
virtual int isFunctionOveride()
{
base refObj;
return (&this->overrideFunc != &refObj.overrideFunc );
}
};

Won't work in his case because base has pure virtual methods so you
can't create an instance of it.

What might work is to go out and create (privately) a class that
derives from base and does not override the method, and then do what
you tried. Don't know if that will work though.

I thought OP's method might work if he instead tried:

&this->overrideFunc != &base::eek:verrideFunc
 
E

Earl Purple

S. I. Becker said:
Is it possible to determine if a function has been overridden by an
object, when I have a pointer to that object as it's base class (which
is abstract)?

highlighting on:
The reason I want to do this is that I want to call this
function if it has been overridden, and not if it hasn't, e.g

But if the base-class implementation is empty (does nothing) then just
call it and if it wasn't implemented you haven't lost anything.

It is usually better anyway if the base class does nothing.

Perhaps your base class function could take a (non-const) int reference
as a parameter instead of returning an int. Then it can "do nothing"
with the reference. (Doesn't have to set it to 0). Is that the design
you are looking for?
 
S

S. I. Becker

Earl said:
> But if the base-class implementation is empty (does nothing) then just
call it and if it wasn't implemented you haven't lost anything.

It is usually better anyway if the base class does nothing.
Agreed.

Perhaps your base class function could take a (non-const) int reference
as a parameter instead of returning an int. Then it can "do nothing"
with the reference. (Doesn't have to set it to 0). Is that the design
you are looking for?

Thanks for your comments. See my new implementation:

int CBase::mightBeOverridden(int i, int j) { return j; }
// Overrides in CDerived# also take 2 args

Stewart
 
E

Earl Purple

S. I. Becker said:
Thanks for your comments. See my new implementation:

int CBase::mightBeOverridden(int i, int j) { return j; }
// Overrides in CDerived# also take 2 args

That wasn't what I had in mind. Actually:

bool CBase::mightModifyOutput( int input, int & output )
{
// the function may modify output or may do nothing with it
return false; // return true if it modified output
}
 
S

S. I. Becker

Earl said:
That wasn't what I had in mind. Actually:

bool CBase::mightModifyOutput( int input, int & output )
{
// the function may modify output or may do nothing with it
return false; // return true if it modified output
}

I realise it's not the same, but it does have similar behaviour - it's
just a question of where the output comes from - return value or reference.

Thanks for your help.

Stewart
 
E

Earl Purple

S. I. Becker said:
I realise it's not the same, but it does have similar behaviour - it's
just a question of where the output comes from - return value or reference.

Thanks for your help.

The difference is that your calling code can call the function (using
its base-class with full polymorphism) and know whether the result (the
2nd parameter which is a non-const reference) was modified by checking
the return value. Although that is not quite the same as knowing if the
base class function was overridden (another class could presumably
override the function, not modify the reference and return false) it
will give you the behaviour you actually want.

To answer the very original post, you could have the base class return
false and all derivations return true, although I doubt your client
code (that uses the base class) will find that particularly useful.
(Whether an output reference is modified is useful in some situations).
 

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,981
Messages
2,570,187
Members
46,730
Latest member
AudryNolan

Latest Threads

Top