从纯虚拟类(A)派生的指针不能访问纯类(B)的重载方法 [英] Pointer derived from pure virtual class(A) can't access overload method from the pure class (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 $ c $中再次可见c>,其中声明了覆盖)。在
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屋!