gpt4 book ai didi

c++ - 关于虚拟参数和默认参数的问题

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:58:08 25 4
gpt4 key购买 nike

我想确认以下事情:

虚拟机制:

如果我有一个基类A并且它有一个Virtual方法,那么在派生类中一般我们不会在函数声明中包含virtual语句。但是,当包含在派生类定义中时,虚拟意味着什么。

class A
{
public:
virtual void something();
}

class B:public A
{
public:
virtual void something();
}

这是否意味着我们要重写从类 B 派生的类中的某些方法?

还有一个问题是,

我有一个类 A,它由三个不同的类派生。现在,在基类 A 中有一个虚方法 anything()。

现在,如果我要向基类 A::anything() 中的该方法添加一个新的默认参数,我也需要将它添加到所有 3 个类中。

我选择的答案:

  1. 如果一个在基类中是虚拟的方法在派生类中被重新定义为虚拟的,那么我们可能意味着它应该在使用该类作为基类的相应派生类中被覆盖。
  2. 是的。如果不覆盖没有任何意义。

请让我知道我的感受(以上2)是否正确。

谢谢,帕万·莫安尔。

最佳答案

virtual 关键字可以在派生类的重写中省略。如果基类中的重写函数是虚函数,则重写也被假定为虚函数。

这个问题很好地涵盖了这一点:In C++, is a function automatically virtual if it overrides a virtual function?


你的第二个问题是关于默认值和虚函数的。基本上,每个覆盖都可以有不同的默认值。但是,通常这不会执行您期望的操作,因此我的建议是:不要混合使用默认值和虚函数

基类函数是否默认,与派生类函数是否默认完全无关。

基本思想是静态类型将用于查找默认值(如果已定义)。对于虚函数,动态类型将用于查找被调用函数。

所以当动态类型和静态类型不匹配时,就会出现意想不到的结果。

例如

#include <iostream>

class A
{
public:
virtual void foo(int n = 1) { std::cout << "A::foo(" << n << ")" << std::endl; }
};

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

int main()
{
A a;
B b;

a.foo(); // prints "A::foo(1)";
b.foo(); // prints "B::foo(2)";

A& ref = b;
ref.foo(); // prints "B::foo(1)";
}

如果您的所有重写都共享相同的默认值,另一种解决方案是在基类中定义一个附加函数,该函数除了使用默认参数调用虚函数外什么都不做。即:

class A
{
public:
void defaultFoo() { foo(1); }
virtual void foo(int n) { .... }
};

如果您的覆盖有不同的默认值,您有两个选择:

  • 同时使 defaultFoo() 成为虚拟的,如果派生类重载一个而不重载另一个,这可能会导致意外结果。
  • 不使用默认值,但在每次调用中明确说明使用的值。

我更喜欢后者。

关于c++ - 关于虚拟参数和默认参数的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6773514/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com