开发者

Determining if a derived class overrides a method from a base class

class B {
virtual int foo();
};

class D : public B {
virtual int foo() { cout<<"D\n"; }
};

int B::foo()
{
   /* how do i tell if this->foo() is overridden by a subclass, or if it wi开发者_JAVA百科ll */
   /* simply recurse into B::foo()? */
   this->foo();
}

main()
{
D d;
d.B::foo();
}


Answer: you can't.

I'd expand if there was anything to expand upon.


One approach is to make foo() pure virtual function in B, and also define it. That way you make sure that the derived classes of B must define foo(). Here is B,

class B
{
public:
        virtual int foo() = 0; //pure virtual function
};

//pure virtual function also has a default implementation!
int B::foo()
{
        std::cout << "B" << std::endl;  
        this->foo(); //this will call the overridden foo() in the derived class!
        return 0;
}

If a derived class of B doesn't implement foo(), then you cannot even create instance of such derived class!

See the complete working code at ideone : http://www.ideone.com/m8O2s

By the way, my personal opinion would be, such design of classes is bad to begin with. What if you call B::foo() from the derive class foo()? Recursive?


I hate even providing this.. but here it is

int B::foo()
{
std::cout << "B" << std::endl;  
if (typeid (*this) != typeid(B))
    this->foo();
return 0;
}

Edit

I want to prove that it works in MSVC++ 2010.

#include "stdafx.h"
#include <iostream>

class B {
public:
virtual int foo();
};

class D : public B {
public:
virtual int foo() {
    std::cout<<"D\n"; return 0; 
}
};

int B::foo()
{
std::cout << "B" << std::endl;  

/* how do i tell if this->foo() is overridden by a subclass, or if it will */
/* simply recurse into B::foo()? */
if (typeid (*this) != typeid(B))
    this->foo();

return 0;
}


int main(int argc, _TCHAR* argv[])
{
D d;
d.B::foo();

B b;
b.foo();
return 0;
}

Output

B
D
B

Proof it won't always work

Change D to this and it won't work anymore

class D : public B { };


As others have pointed out, there is no reliable way to do this. I urge you to rethink your design...


The safest way is by not overriding foo() at all, but allow overriding of an OnFoo() function which is called from the baseclass if you cannot trust your programmers. MFC does a lot of this to ensure some default behaviour (rather than protect against recurision).

Then, also at a static level, anything that implements OnFoo() is easily spotted with a 'Find in files'.

E.g. (not tested for syntax/compilation and not threadsafe)

class B
{
public:
    B()
    {
        m_bInFoo=false;
    } 

    int foo()
    {
        if( !m_bInFoo )
        {
            m_bInFoo=true;

            int nRet = OnFoo();

            m_bInFoo=false;

            return nRet;
        }

        return 0;// probably throw exception
    }

protected:
    // inherited classes override OnFoo(), and never call OnFoo();
    virtual int OnFoo(){ return 0 };

private:
    bool m_bInFoo;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜