类的C ++函数重载

时间:2014-10-02 16:52:11

标签: c++ inheritance overloading

我有3个班级

class A { 
//...
}

class B : public A {
//...
}

C班:

#include "A.h"
#include "B.h"

class C
{
   void method(A anObjOfA);
   void method(B anObjOfB);
}

现在,如果我这样做

B* ptr = new B();
A* ptrToB = ptr;
c.method(*ptrToB);

它调用A类型的对象的方法,而不是继承的实际类型B ..我怎样才能确保调用inheritence-tree中最深的对象的正确函数,而不是在编译时实际知道它的类型?

PS:我确定这是一个noob问题,对于我的生活,我在这里找不到任何结果,因为每个人都在忙着理解“虚拟”关键字,这对我来说非常清楚,但是这不是问题。

4 个答案:

答案 0 :(得分:5)

因为解析函数重载是在编译时完成的。当你调用函数时,它只能看到指针的A部分,即使它可以指向B。

也许您想要的是以下内容:

class A
{
public:
    virtual void DoWorkInC()
    {
        cout << "A's work";
    }
    virtual ~A() {}
};

class B : public A
{
public:
    virtual void DoWorkInC()
    {
        cout << "B's work";
    }
};

class C
{
   void method(A& a)
   {
        a.DoWorkInC();
   }
}

答案 1 :(得分:0)

让你的A,B类在其respectivbe类中实现虚函数:

class A { 
//...
   public:
     virtual void doTask(); 
};

class B : public A {
//...
   public:
     void doTask(); 
};

Ket A :: doTask()和B :: doTask()以对象特定的方式执行各自的任务,即A :: doTask()执行具有对象集可见性的任务,并且B :: doTask()用于将对象集的可见性设置为B对象。 现在,让这个电话是这样的:

B* ptr = new B();
A* ptrToB = ptr;
c.method(ptrToB); // pointer is passed

在C :: method(A * ptr)中,它可能类似于:

void C::method(A * ptr) {
  ptr->doTask(); this would actuall call A::doTask() or B::doTask() as dynamically binded
}

答案 2 :(得分:0)

编译器不够聪明,无法猜出你想要调用哪种方法。在您的情况相同的情况下,您可能实际上想要调用第一个版本,因为您使用的是A*。这让程序员继续工作:具体。如果您不想使用ptr(根据需要调用第二个版本),则需要专门投射它:

c.method(*((B*)ptrToB));
使用动态演员

或更好:

c.method(*dynamic_cast<B*>(ptrToB));

这可能是不安全的,因为你是“向下转发”,在这种情况下,动态强制转换可能会抛出异常并且C样式强制转换不会但会导致内存泄漏。你必须非常小心。

答案 3 :(得分:0)

感谢@texasbruce我找到了答案,RTTI

代码如下所示:

A* someAOrBPtr = ...
...
B* testBPtr = dynamic_cast<B*>(someAOrBPtr);
if( testBPtr ){
    // our suspicions are confirmed -- it really was a B
    C->method(testBPtr);
}else{
    // our suspicions were incorrect -- it is definitely not a B.
    // The someAOrBPtr points to an instance of some other child class of the base A.
    C->method(someAOrBPtr);
};

编辑:事实上,我可能会在C-&gt;方法中进行动态转换,因此只有一个

  

C :: method(A * ptrOfBase)

然后在C的一个'方法'中做适当的事情(取入或取出C的各个容器成员变量)。