c – 代码执行派生类方法,但从基类方法获取默认参数

有人可以解释为什么下面的代码的结果将是“B类:: 1”?

为什么派生类的虚方法使用基类的默认参数而不是自己的默认参数?对我来说这很奇怪.提前致谢!

码:

#include <iostream>

using namespace std;

class A
{
public:
    virtual void func(int a = 1)
    {
        cout << "class A::" << a;
    }
};

class B : public A
{
public:
    virtual void func(int a = 2)
    {
        cout << "class B::" << a;
    }
};

int main()
{
    A * a = new B;
    a->func();

    return 0;
}
最佳答案
因为默认参数是根据它的静态类型(即变量本身的类型,如A& a中的A& a)解析的.

稍微修改您的示例:

#include <iostream>

class A
{
public:
    virtual void func(int a = 1)
    {
        std::cout << "class A::" << a << "\n";
    }
};

class B : public A
{
public:
    virtual void func(int a = 2)
    {
        std::cout << "class B::" << a << "\n";
    }
};

void func(A& a) { a.func(); }

int main()
{
    B b;
    func(b);
    b.func();

    return 0;
}

我们观察以下输出:

class B::1
class B::2

ideone行动.

由于这个原因,不建议虚函数更改默认值.不幸的是,我不知道任何编译器警告这个结构.

技术说明是有两种处理默认参数的方法:

>创建一个新函数充当trampoline:void A :: func(){func(1); }
>在呼叫站点添加缺少的参数a.func()=> a.func(/ * *魔/ 1)

如果它是前者(假设A :: func也被声明为虚拟),那么它会像你期望的那样工作.然而,后一种形式是选举产生的,或者是因为当时没有预见到虚拟问题,或者因为它们被认为是无关紧要的(如果有的话……).

转载注明原文:c – 代码执行派生类方法,但从基类方法获取默认参数 - 代码日志