确定派生类是否重写基类的方法

发布于 2024-10-09 18:27:33 字数 311 浏览 0 评论 0原文

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

夏天碎花小短裙 2024-10-16 18:27:33

答案:你不能。

如果有什么可以扩展的,我会扩展。

Answer: you can't.

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

塔塔猫 2024-10-16 18:27:33

一种方法是在B中使foo()纯虚函数也定义它。这样您就可以确保 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

顺便说一下,我个人的观点是,这样的类设计一开始就不好。如果从派生类 foo() 调用 B::foo() 会怎样?递归?

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?

音栖息无 2024-10-16 18:27:33

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

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

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 { };
花桑 2024-10-16 18:27:33

正如其他人指出的那样,没有可靠的方法可以做到这一点。我敦促你重新考虑你的设计......

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

听,心雨的声音 2024-10-16 18:27:33

最安全的方法是根本不重写 foo(),但如果您不信任程序员,则允许重写从基类调用的 OnFoo() 函数。 MFC 做了很多这样的事情来确保某些默认行为(而不是防止递归)。

然后,同样在静态级别,任何实现 OnFoo() 的内容都可以通过“在文件中查找”轻松发现。

例如(未测试语法/编译且不是线程安全的)

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

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文