确定派生类是否覆盖基类中的方法

时间:2010-12-29 17:11:31

标签: c++ virtual rtti

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 will */
   /* simply recurse into B::foo()? */
   this->foo();
}

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

5 个答案:

答案 0 :(得分:8)

答案:你不能。

如果有任何可扩展的内容,我会扩展。

答案 1 :(得分:2)

一种方法是在foo()中制作B 纯虚拟功能也定义它。这样,您可以确保B 的派生类必须定义foo()。这是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;
}

如果B的派生类没有实现foo(),那么你甚至无法创建这样的派生类的实例!

请参阅ideone上的完整工作代码:http://www.ideone.com/m8O2s

顺便说一下,我的个人意见是,这样的课程设计开始是不好的。如果从derive类foo()调用B::foo()怎么办?递归?

答案 2 :(得分:1)

我讨厌提供这个......但是这里是

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

修改

我想证明它在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;
}

输出

B
D
B

证明它不会一直有效

将D更改为此,它将不再起作用

class D : public B { };

答案 3 :(得分:0)

最安全的方法是根本不重写foo(),但允许覆盖从基类调用的OnFoo()函数,如果你不能信任你的程序员。 MFC做了很多工作来确保一些默认行为(而不是防止重复)。

然后,在静态级别,任何实现OnFoo()的东西都很容易被“查找文件”所发现。

E.g。 (没有测试语法/编译而不是线程安全)

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;
}

答案 4 :(得分:0)

正如其他人所指出的,没有可靠的方法来做到这一点。我劝你重新考虑你的设计......