问题
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;
}
};
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"));
}
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;
inside Abstract2
class.
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.
Here's a link to play with it online where the example was created: https://godbolt.org/z/gxKpzN
回答1:
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;
};
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
.
来源:https://stackoverflow.com/questions/59756738/pointer-derived-from-pure-virtual-classa-cant-access-overload-method-from-the