无法从继承的类分配指向方法的指针
Can't assign a pointer to method from an inherited 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(){}
};
你能解释一下为什么我不能那样做吗
bool (IBaseA::*ptr)(std::string&) = &BaseA::sayHello;
错误:无法转换'bool (BaseA::)(std::string&){也称为bool(BaseA::)(std::basic_string&)}' to 'bool(IBaseA::)(std::string&){也称为bool(IBaseA:: ) (std:: basic_string&)}"初始化
我不明白为什么我不能这样做。
但是如果我把赋值改为
bool (IBaseA::*ptr)(std::string&) = &IBaseA::sayHello;
那么我可以毫无问题地使用这个指针
BaseA A;
(A.*ptr)(str);
编辑:谢谢你的回答,我在想,因为所有的地址都在虚表中,根据我从维基百科所理解的,它们是相同的位置。
指针到成员的转换与一般的指针转换相反。可以将指向派生类的指针转换为指向基类的指针,但反之则不行。可以将基类的指针指向成员转换为派生类的指针指向成员,但反之则不行。
始终考虑转换是否有效。
普通指针:所有BaseA
的实例都是IBaseA
的实例,因此转换是合法的。并不是所有的IBaseA
实例都是BaseA
实例,所以你不能以其他方式转换。
成员指针:IBaseA
的所有成员都存在于BaseA
中,因此可以将IBaseA
的成员指针转换为BaseA
的成员指针。然而,BaseA
的所有成员并不是都存在于IBaseA
中,因此不能反过来进行转换。
给定两个指向成员的指针类型T C1::*P1
和T C2::*P2
(其中T可能是函数类型),如果C2派生自C1,则只能将P1转换为P2。注意,这是指向对象的指针的逆操作,对象指针只能向上转换。
原因是,如果有一个指向基类成员的指针,则任何子类都保证也具有该成员,因为它继承了该成员。反之则不适用。
这是基本的类型转换规则。它不会因为你取的指针恰好是基类中存在的虚函数的重写而改变
真正的答案可能是"因为语言规范说你不能",然而,想想你在尝试做什么:
bool (IBaseA::*ptr)(std::string&) = &BaseA::sayHello;
本质上,这读作:我想要一个名为ptr的变量,它是一个指向IBaseA成员函数的指针,我想让它指向BaseA中的方法'sayHello'。
是的,BaseA中的sayHello方法覆盖了IBaseA中的sayHello方法,但它们仍然是不同的方法。想象一下,如果您尝试使用指针来调用类型为IBaseA的对象上的方法,而实际上不是 BaseA—这在语法上是允许的,但是您会期望发生什么?
换句话说,将指向派生类成员的指针赋值给声明为指向基类成员的变量,将破坏静态类型安全。
虽然这看起来有点违反直觉,但是不能将派生类型的指向成员的指针转换为指向基类型的指向成员的指针。正确的转换是另一种方式:您可以将指向基的成员指针转换为指向派生的成员指针。
原因是,如果基类具有该成员,则派生类型保证具有该成员,但反之则不为真(即,指向派生类型的成员的指针可以指向已添加且不存在于基类中的成员)。 你可能错过的另一件事是,指针到成员函数是多态的,也就是说,你可以存储&IBase::sayHello
,如果它应用的成员类型是Base
,它将调用Base::sayHello
。
- 将一个类的方法指针存储到另一个类中
- 如何调用返回类方法指针的类方法
- 通过reinterpret_casting方法指针从指针调用派生类的方法。这是 UB 吗?
- 泛型方法指针.reinterpret_cast指向不同类的方法指针,这是 UB 吗?
- C++;类方法指针;λ;将 lambda 作为成员函数指针传递;
- 使用模板、方法指针和字符串键入推导
- 将方法指针作为整数参数发送到C#的C 方法
- 从C 中的VTable获取方法指针
- 模板化方法指针 - 无法匹配函数参数的指针
- 获取特定的模板重载方法指针
- 如何将方法指针声明为Typedef方法参数
- 如何将方法指针类型转换为函数指针类型
- 如何在使用 pthreads 时将方法指针作为函数参数传递C++
- 方法指针映射,编译器说他们不接受任何参数
- C# 方法指针,如 C++ 中的指针
- c++创建新的LinkedList类:Clear()方法指针被释放未分配
- 尝试获取类方法指针时出现E_NOINTERFACE
- 传递和强制转换方法指针
- 常量方法指针的类型是什么
- 将对象的方法指针传递给接受 [静态方法指针/全局函数] 指针的函数