C++ 多态性和默认参数

标签 c++

我有这些类(class):

class Base
{
    public:
        virtual void foo(int x = 0)
        {
            printf("X = %d", x);
        }
};

class Derived : public Base
{
    public:
        virtual void foo(int x = 1)
        {
            printf("X = %d", x);
        }
};

当我有:

Base* bar = new Derived();
bar->foo();

我的输出是“X = 0”,即使 foo 是从 Derived 调用的,但是当我有:

Derived* bar = new Derived();
bar->foo();

我的输出是“X = 1”。这种行为是否正确? (从声明类型中选择默认参数值,而不是从实际对象类型中选择)。这会破坏 C++ 多态性吗?

如果有人在不指定实际函数参数的情况下使用虚函数并使用函数的默认参数,会导致很多问题。

最佳答案

即使你覆盖了一个函数,默认参数也会被保留!而这种行为是正确的。让我从 C++ 标准中搜索引用。

C++ 标准的 §8.3.6/10 [默认参数] 说,

A virtual function call (10.3) uses the default arguments in the declaration of the virtual function determined by the static type of the pointer or reference denoting the object. An overriding function in a derived class does not acquire default arguments from the function it overrides.

标准本身的例子

struct A {
     virtual void f(int a = 7);
};
struct B : public A {
     void f(int a);
};
void m()
{
    B* pb = new B;
    A* pa = pb;
    pa->f(); //OK, calls pa->B::f(7)
    pb->f(); //error: wrong number of arguments for B::f()
}

此外,它不仅被保留,而且每次调用函数时都会计算它:

§8.3.6/9 说,

Default arguments are evaluated each time the function is called

关于C++ 多态性和默认参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5273144/

相关文章:

javascript - 从 chrome 打开外部应用程序?

c++ - 在运算符 new 的重载中调用 new 表达式

c++ - 虚拟继承中的构造函数顺序

c++ - 只是想知道是否有可能丢失数据?

c++ - 权限被拒绝,正在运行 C++ 程序 bash

c++ - 如何将变量的内容存入const char*?

c++ - 切片 vector

c++ - 使用SFINAE,如何避免 'has no member named ...'

c++ - 使用 Boost [C++] 将 http 文件内容读取为字符串

c++ - 学习阅读 GCC 汇编器输出