I have this two class:
class IBaseA
{
public:
virtual bool sayHello(std::string&) = 0;
~IBaseA(){}
};
class BaseA: public IBaseA
{
public:
virtual bool sayHello(std::string &str)
{
std::cout << "Hello " << str << std::endl;
return (true);
}
BaseA(){}
};
Can you explain me why I'm not able to do something like that
bool (IBaseA::*ptr)(std::string&) = &BaseA::sayHello;
error: cannot convert 'bool (BaseA::)(std::string&) {aka bool (BaseA::)(std::basic_string&)}' to 'bool (IBaseA::)(std::string&) {aka bool (IBaseA::)(std::basic_string&)}' in initialization
I don't understand why I can't do something like this.
But if I change the assignment to
bool (IBaseA::*ptr)(std::string&) = &IBaseA::sayHello;
then I can use this pointer without any problems
BaseA A;
(A.*ptr)(str);
edit: Thanks for the answers, I was thinking that since all the addresses are in the vtable, they are the same location according of what I understood from wikipedia.
Pointer-to-member conversions work opposite to normal pointer conversion. You can convert a pointer to derived class into a pointer to base class, but not vice versa. You can convert a pointer-to-member of base class to pointer-to-member of derived class, but not vice versa.
Always think whether the conversion is valid.
Plain pointers: All instances of BaseA
are instances of IBaseA
, so that conversion is legal. Not all IBaseA
instances are BaseA
instances, so you can't convert the other way.
Pointers-to-member: All members of IBaseA
are also present in BaseA
, so you can convert a pointer-to-member of IBaseA
into a pointer-to-member of BaseA
. Not all members of BaseA
are present in IBaseA
, however, so conversion the other way round is not possible.
Given two pointer-to-member types T C1::*P1
and T C2::*P2
(where T might be a function type), you can only convert P1 to P2 if C2 derives from C1. Note that this is the inverse of pointers to objects, where you can only upcast.
The reason is that if you have a pointer to a member of the base class, any subclass is guaranteed to have that member too, since it inherited it. The other way round does not apply.
This is the basic type conversion rule. It doesn't change just because that particular pointer you are taking there happens to be an override of a virtual function that exists in the base class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With