首页 > 解决方案 > 更改派生类中虚函数的参数列表

问题描述

代码 1

#include<iostream>
struct b
{
    virtual void f1(void)
    {
        std::cout<<"b->f1\n";   
    }
};

struct d:public b
{
    void f1(int x)
    {
        std::cout<<"d->f1\n";
    }
};

int main()
{
    b *p;
    d d1;
    p=(b*)&d1;
    
    p->f1(4); // this gives error
    
}

输出

[Error] no matching function for call to 'b::f1(int)'

代码 2

#include<iostream>
struct b
{
    virtual void f1(void)
    {
        std::cout<<"b->f1\n";   
    }
};

struct d:public b
{
    virtual void f1(int x)
    {
        std::cout<<"d->f1\n";
    }
};

int main()
{
    b *p;
    d d1;
    p=(b*)&d1;
    
    p->f1(4); // this gives error
    
}

输出:

[Error] no matching function for call to b::f1(int)

virtual在第二个代码中,我只是在派生类 fun 中明确编写。

对于这两种情况,编译器都在进行早期绑定,因为它在基类中找到了这些函数。意味着派生类函数f1没有变成虚拟的?

为什么在案例 1 中它没有成为虚拟功能?还有在我写明确virtual关键字的情况2中?

另外我读到虚拟功能应该在覆盖的情况下使用,不是在过度隐藏的情况下使用,这是真的吗?

标签: c++polymorphismoverridingvirtual-functions

解决方案


虚函数背后的要点是代码可以使用指向基类的指针来调用子类的方法,甚至不知道子类的存在

换句话说,您的代码实际上等同于:

#include<iostream>

struct b
{
    virtual void f1(void)
    {
        std::cout<<"b->f1\n";   
    }
};

// Implemented somewhere else entirely.
b* some_function_that_might_returns_a_d();

int main()
{
    b *p;
    p = some_function_that_might_returns_a_d();
    
    p->f1(4); // this gives error    
}

编译器看到的只是f1(void),它没有其他东西可以使用。这就是为什么它抱怨f1(4)没有意义。

编译器恰好能够d在您的示例中看到这一事实只是偶然的,不会影响任何事情。只要您在 type 的指针上调用方法b,您就可以在 的任何子类上调用方法b,即使在尚不存在的类上也是如此。但是,要使其正常工作,只能使用由基类声明的方法。


推荐阅读