C++ 派生类原因的虚函数“;“不是成员”;从基调用时出错

C++ 派生类原因的虚函数“;“不是成员”;从基调用时出错,c++,compiler-errors,virtual,C++,Compiler Errors,Virtual,不应该a1getgetB,因为它实际上是指向B的指针?类a中必须有一个成员函数: test.cpp(28): error C2039: 'getB' : is not a member of 'A' 之后,当您调用a1->getB()时,它将调用类B的成员函数 另一种方法是在a1上使用dynamic_cast: virtual int getB() { // do something or not } A*a1=新的B(10); B*b1=动态_型铸造(a1); std::cout get

不应该
a1
get
getB
,因为它实际上是指向
B
的指针?

类a中必须有一个成员函数:

test.cpp(28): error C2039: 'getB' : is not a member of 'A'
之后,当您调用
a1->getB()
时,它将调用类B的成员函数

另一种方法是在a1上使用
dynamic_cast

virtual int getB()
{
 // do something or not
}
A*a1=新的B(10);
B*b1=动态_型铸造(a1);

std::cout getA()类a中必须有一个成员函数:

test.cpp(28): error C2039: 'getB' : is not a member of 'A'
之后,当您调用
a1->getB()
时,它将调用类B的成员函数

另一种方法是在a1上使用
dynamic_cast

virtual int getB()
{
 // do something or not
}
A*a1=新的B(10);
B*b1=动态_型铸造(a1);

std::cout getA()编译器不知道
a
的动态类型信息。可以使用以下命令将其强制转换为其动态类型:

dynamic_cast(a1)->getB();

编译器不知道
a
的动态类型信息。可以使用以下命令将其强制转换为其动态类型:

dynamic_cast(a1)->getB();

虽然a1是指向B类对象的指针,但编译器直到运行时才知道a1指向B类对象。因此,在编译时,您将遇到一个错误,因为类a中没有getB方法。

虽然a1是指向B类对象的指针,但编译器直到运行时才知道a1指向B类对象。因此在编译时,您将遇到错误,因为类A中没有getB方法。

编译器会告诉您确切原因:

dynamic_cast<B*>(a1)->getB();
编译器根据指针的类型进行编译时检查,因为它无法在
a
中找到它报告的方法。请注意,在编译时,编译器可能知道也可能不知道指针
a1
指向什么对象,它可能是
A
B
或公开派生自
A
的任何类。编译器只检查指针的类型,并检查被访问的成员是否属于该类。
对于您来说,
a1
指向
B
的对象,因此可以像
B
一样处理,但是对于编译器来说,
a1
a
类型的指针,在编译时它只将其视为
a


虽然“为什么这不起作用”的答案已经在上面很好地讨论过了,但我认为我应该在“你如何解决这个问题”中加入

简单的答案是为
a
实现一个
getB()
。这通常是正确的做法-如果在不具有此属性的对象上“禁止”调用
getB
,那么请对此采取措施-打印错误、退出程序,或者当有人在代码中出错时,执行任何“正确”的操作(最好在某个地方打印一条消息,然后停止,这样就可以清楚地知道出了什么问题,并且可以对其进行调试)

另一种方法,例如使用dynamic cast,也可以。但是您仍然需要知道对象是否是
B
类,或者检查指针是否返回NULL

虚拟函数的要点在于,您可以使用派生类中的新变量覆盖基类中的函数。它不支持在派生类中添加新函数。支持“新函数”的方法是,例如,添加一个参数:

'getB' : is not a member of 'A'
A类
{
公众:
...
虚拟整数获取(字符v)
{
如果(v='A')返回A;
其他的
{

编译器会告诉您确切的原因:

dynamic_cast<B*>(a1)->getB();
编译器根据指针的类型进行编译时检查,因为它无法在
a
中找到它报告的方法。请注意,在编译时,编译器可能知道指针
a1
指向的对象,也可能不知道,它可能是
a
B
或任何公开派生自
a
的类>。编译器只检查指针的类型,并检查被访问的成员是否属于该类。
对于您来说,
a1
指向
B
的对象,因此可以像
B
一样处理,但是对于编译器来说,
a1
a
类型的指针,在编译时它只将其视为
a


虽然“为什么这不起作用”的答案已经在上面很好地讨论过了,但我认为我应该在“你如何解决这个问题”中加入

简单的答案是为
a
实现一个
getB()
。这通常是正确的做法-如果在没有此属性的对象上“禁止”调用
getB
,那么就对它做些什么-打印错误,退出程序,或者做任何“正确”的事情当有人在代码中出错时(最好在某个地方打印一条消息,然后停止,这样就可以清楚地知道出了什么问题,并且可以对其进行调试)

另一种方法,例如使用dynamic cast,也可以。但是您仍然需要知道对象是否是
B
类,或者检查指针是否返回NULL

虚拟函数的要点在于,您可以使用派生类中的新变量覆盖基类中的函数。它不支持在派生类中添加新函数。支持“新函数”的方法是,例如,添加一个参数:

'getB' : is not a member of 'A'
A类
{
公众:
...
虚拟整数获取(字符v)
{
如果(v='A')返回A;
其他的
{

我删除了我的答案并将相关内容添加到你的答案中,这样我们就有了一个完整的答案。希望你可以随意删除修改过的内容。我删除了我的答案并将相关内容添加到你的答案中,这样我们就有了一个完整的答案。希望它应该I’我对你没意见,或者可以随意删除修改过的内容。