0
#include<iostream>

class A {
private :
    int _a;

public :
    A(int i=0) : _a(i){}
    virtual void setA(int i) { _a = i;}
    virtual int getA(){ return _a;}
};

class B : public A
{
private :
    int _b;

public :

    B(int i) : _b(i){}
    virtual void setB(int i) { _b = i;}
    virtual int getB(){ return _b;}
};

int main(){
A* a1 = new B(10);
std::cout << a1->getA() << "\t " << a1->getB() << std::endl;
return 0;
}

编译时出现以下错误:

test.cpp(28): error C2039: 'getB' : is not a member of 'A'

不应该a1得到getB,因为它实际上是一个指针B

4

4 回答 4

3

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

'getB' : is not a member of 'A'

编译器根据指针的类型A进行编译时检查,因为它在报告中找不到方法。请注意,在编译时,编译器可能知道也可能不知道指针a1指向的对象,它可能是AB任何从A. 编译器只检查指针的类型并检查被访问的成员是否属于该类。
对你来说,a1指向一个对象,B因此可以被视为,B但对于编译器a1来说,它是一个类型的指针,A在编译时它只将它视为A.


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

简单的答案是实现一个getB()for A。这通常是正确的做法 - 如果以某种方式“禁止”调用getB不具有此属性的对象,则对其进行处理 - 打印错误,退出程序,或者当有人“正确”时在代码中出现问题(最好在某处打印一条消息,然后停止,以便清楚出了什么问题并可以对其进行调试)。

替代方案,例如使用动态转换,也将起作用。但是您仍然必须知道对象是否是B类 - 或者检查指针是否返回 NULL。

虚函数的全部意义在于您用派生类中的新变体覆盖基类中的那些。它不支持在派生类中添加新函数。支持“新功能”的方法是例如添加一个参数:

class A
{
 public: 
    ...
    virtual int get(char v)
    {
       if (v == 'A') return _a;
       else
       {
          std::cerr << "Error: Requesting invalid variable: '" << v << "'" << std::endl;
          return -1;
      }
    }
    ...
}


class B: public A
{
   ...
   virtual get(char v)
   {
      if (v == 'B')
         return b;
      return A::get(v);
   }

   ...
}

现在,只需稍作修改即可:

std::cout << a1->get('A') << "\t " << a1->get('B') << std::endl;
于 2013-03-30T12:42:35.057 回答
1

您必须在 A 类中有一个成员函数:

virtual int getB()
{
 // do something or not
}

之后,当您调用a1->getB()它时,它将调用 B 类的成员函数。

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

A* a1 = new B(10);
B* b1=dynamic_cast<B*>(a1);
std::cout << b1->getA() << "\t " << b1->getB() << std::endl;
于 2013-03-30T12:25:22.293 回答
1

编译器不知道a的动态类型信息。您可以使用以下方法将其转换为动态类型dynamic_cast

dynamic_cast<B*>(a1)->getB();

现场演示

于 2013-03-30T12:35:06.987 回答
0

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

于 2013-03-30T12:37:35.220 回答