【问题标题】:观察(检查):相同的成员函数名,不同的签名,一个作为虚拟成员
【发布时间】:2022-01-23 13:09:23
【问题描述】:

恐怕这是不可能的:

class A {

public:

    A(){}

    virtual string s() = 0
            string s(int i) {
                auto j = this->s(); 
                ... modify j ...
                return j;
};

class B: public A{

public:

    B() : A() {}

    string s() override {
       return string("Class B"); // just some string
    }
};

换句话说:你不能有两个成员函数变体,只有一个是虚拟的?这个观察正确吗?

【问题讨论】:

  • 为什么你认为你不能?请发布minimal reproducible example,说明您的问题所在。
  • @stustd 你可能在一个类中有同名的虚函数和非虚函数。
  • 你做了什么观察?您发布的代码会导致一些编译器错误,但与virtualoverride 无关。
  • @Vlad 确实,这就是问题所在:是否可以在一个类中拥有同名的虚拟和非虚拟函数(尽管它们的签名显然不同)?
  • @stustd 请在下面查看我的答案。

标签: c++ class scope virtual using-declaration


【解决方案1】:

您可以在基类和派生类中使用同名的虚函数和非虚函数。

在您问题中的类示例中,派生类 B 中的虚函数 s 的定义隐藏了在基类 A 中声明的同名非虚函数。

string s() override {
   return string("Class B"); // just some string
}

要使其在派生类的范围内可见,您可以使用 using 声明。

这是一个演示程序。

#include <iostream>
#include <string>

int main()
{
    struct A
    {
        std::string f( int i ) const 
        {
            return f() + '(' + std::to_string( i ) + ')';
        }

        virtual std::string f() const
        {
            return "struct A";
        }

        virtual ~A() = default;
    };

    struct B : A
    {
        using A::f;

        virtual std::string f() const override
        {
            return "struct B";
        }
    };

    B b;

    std::cout << b.f( 1 ) << '\n';

    A &rb = b;

    std::cout << rb.f( 2 ) << '\n';

    A a;

    std::cout << a.f( 3 ) << '\n';
}

程序输出是

struct B(1)
struct B(2)
struct A(3)

【讨论】:

  • 哇,这很棘手......;我自己也想不通。谢谢!一些后续问题:-“隐藏”,是在运行时解析 b/c 虚拟方法吗? - 这是一个常见的习惯用法,还是最好/建议避免将具有相同名称的成员函数的虚拟和非虚拟混合在一起?
  • @stustd 隐藏是静态发生的。内部范围内的任何名称都会在外部范围内隐藏相同的名称。
猜你喜欢
  • 2013-01-15
  • 2011-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-22
相关资源
最近更新 更多