从纯虚拟类(A)派生的指针不能访问纯类(B)的重载方法 [英] Pointer derived from pure virtual class(A) can't access overload method from the pure class (B)

查看:86
本文介绍了从纯虚拟类(A)派生的指针不能访问纯类(B)的重载方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑一下,我有两个纯虚拟类,一个是从另一个类派生的,一个具体类是从上一个提到的派生而来的:

Consider I have two pure virtual classes, one deriving from the another and a concrete class deriving from the last mentioned:

#include <iostream>
#include <string>

class Abstract1
{
public:
    virtual ~Abstract1() { };
    virtual void method(int a) = 0;

protected:
    Abstract1() = default;
};

class Abstract2: public Abstract1
{
public:
    virtual ~Abstract2() { };
    virtual void method(char c, std::string s) = 0;

protected:
    Abstract2() = default;
};

class Concrete : public Abstract2
{
public:
    void method(int a) override
    {
        std::cout << __PRETTY_FUNCTION__ << "a: " << a << std::endl;
    }

    void method(char c, std::string s) override
    {
        std::cout << __PRETTY_FUNCTION__ << "c: " << c << "; s: " << s << std::endl;
    }
};

当我创建 Abstract2 * 我无法从 Abstract1 访问重写方法。

When I create a pointer of the type Abstract2* I can't have access to the override method from Abstract1.

int main()
{
    Concrete c;
    c.method(42);
    c.method('a', std::string("string"));

    Abstract2 *ptr_a2 = &c;
    ptr_a2->method(13); //Error
    ptr_a2->method('b', std::string("string2"));
}

我遇到以下错误,说唯一存在的方法是 Absctract2 重载:

I got the following error, saying that the only existing method is the Absctract2 overloaded:

<source>: In function 'int main()':
<source>:49:22: error: no matching function for call to 'Abstract2::method(int)'

   49 |     ptr_a2->method(13);

      |                      ^

<source>:22:18: note: candidate: 'virtual void Abstract2::method(char, std::string)'

   22 |     virtual void method(char c, std::string s) = 0;

      |                  ^~~~~~

<source>:22:18: note:   candidate expects 2 arguments, 1 provided

有人知道为什么会发生或如何解决吗?
我的意思是,我得到的唯一合理的解决方案是添加

Does anybody know why does it happen or how to fix it? I mean, the only reasonable solution I got was to add

virtual void method(int a) override = 0;

Abstract2 类内部。

这是姓名隐藏的情况吗?为什么只在指针上而不是在具体类上呢?参数的数量不只是封闭类型。

Is it a case of "name hiding"? Why only on pointer and not on the Concrete class then? The number of parameters are different is not only a close-type thing.

以下是创建示例的在线链接:
https://godbolt.org/z/gxKpzN

Here's a link to play with it online where the example was created: https://godbolt.org/z/gxKpzN

推荐答案

是的,名称隐藏在 Abstract2 中(但在 Concrete ,其中声明了覆盖)。在 Abstract2 中使其易于访问的最简单方法是使用语句添加

Yes, the name is hidden in Abstract2 (but visible again in Concrete, where the override is declared). The easiest way to make it accessible in Abstract2 is to add a using statement:

class Abstract2: public Abstract1
{
public:
    using Abstract1::method;
    virtual void method(char c, std::string s) = 0;
};

请注意,成员函数是纯虚函数还是具有定义并不重要,我们看到无论是查看具体的 Abstract2 还是键入 Abstract2 的引用或指针。

Note that it's not relevant whether the member function is pure virtual or has a definition, and we see the same whether looking at a concrete Abstract2 or a reference or pointer to type Abstract2.

这篇关于从纯虚拟类(A)派生的指针不能访问纯类(B)的重载方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆