2011-01-24 95 views
2

我在正确处理方法覆盖抽象类在我的类层次结构中存在 时遇到问题。 我会尽力解释:抽象类中的C++和继承

class AbstractClass{ 
public: 
    virtual void anyMethod() = 0; 
}; 

class A : public AbstractClass { 
    void anyMethod() { 
     // A implementation of anyMethod 
     cout << "A"; 
    } 
}; 

class B : public AbstractClass { 
    void anyMethod() { 
     // B implementation of anyMethod 
     cout << "B"; 
    } 
}; 

AbstractClass *ptrA, *ptrB; 

ptrA = new A(); 
ptrB = new B(); 
ptrA->anyMethod(); //prints A 
ptrB->anyMethod(); //prints B 

Ok..previous例如,做工精细。该抽象类 方法anyMethod的具体实施将在运行时被调用。 但抽象类是由具有不虚 的方法称为anyMethod另一个基类派生:

class OtherClass { 
public: 
    void anyMethod() { 
     cout << "OtherClass"; 
    } 
}; 

class AbstractClass : public OtherClass { 
public: 
    virtual void anyMethod() = 0; 
}; 

//A and B declared the same way as described before. 

现在,如果我尝试类似的东西:

ptrA = new A(); 
ptrB = new B(); 
ptrA->anyMethod(); //prints OtherClass 
ptrB->anyMethod(); //prints OtherClass 

我是什么误会? 有没有解决方案使ptrA和ptrB打印A和B而不使用cast,typeid等?

+0

请格式化您的代码 – Elalfer 2011-01-24 17:47:44

+3

A和B也应在第二种情况下打印。你从描述中遗漏了什么? – vitaut 2011-01-24 17:53:42

回答

0

感谢您的答案..帮助我了解了很多问题。 实际上我发布了一些错误的代码,因为我误解了真正的问题。 无论如何,我想我部分解决了我的问题。 下面的代码:

#include <iostream> 

`` using namespace std; 

class Other{ 

public: 

void foo(){ 
     cout << "Other\n"; 
} 

void foo(int a){} 
}; 

class Abstract : public Other{ 

public: 
virtual void foo() {}; 
virtual void foo(int c){ 
     Other::foo(c); 
} 
}; 

class A : public Abstract{ 

public: 

void foo(){ 
     cout << "A\n"; 
} 
}; 

class B : public Abstract{ 

public: 

void foo(){ 
     cout << "B\n"; 
} 
}; 
int main(){ 

cout << "main\n"; 

Abstract * ptrA = new A(); 
Abstract * ptrB = new B(); 

Other *o = new Other(); 
o->foo(); 

ptrA->foo(); 
ptrB->foo(); 
ptrB->foo(3); //can't no more use the method foo with different signatures implemented in the base class Other, unless I explicitly redefined in the class Abstract 
dynamic_cast<Other*>(ptrB)->foo(3);//can't dynamic_cast from derived to base 

我做了两个错误:

  1. 在我真正的代码(而不是简化版本之前发布)我忘了申报虚拟 函数foo()

  2. 即使宣布虚拟是不够的。实际上,该函数的所有实现都必须包含在Abstract类中,以便对子类A和b可见。否则不会编译。

我不知道它是否可以是一个干净的解决方案..事实上,我需要包装所有foo方法签名。

2

如果anyMethod在您有指针或引用的基类中声明为虚拟,那么应该应该虚拟查找并正确打印A和B.如果不是,那么你就无能为力(除了把它变成虚拟的)。

5

你为什么不这样做:

class OtherClass 
{ 
    public: 
    virtual void anyMethod() 
    { 
     cout << "OtherClass"; 
    }; 
} 

这应该解决您的问题

2

我认为,如果你想在AB覆盖在OtherClass的方法不虚,那么,覆盖不是隐含的。

我相信有一种方法可以明确地覆盖这些函数,然后看看。

1

DeadMGs的答案当然是正确的。但是,如果你不能改变OtherClass了Methode(例如,从第三方的lib的),你可能想试试这个:

是指针ptrA,在低例如OtherClassptrBAbstractClass

如果他们是OtherClass我会期待你描述的行为。你可以尝试铸造指针AbstractClass则:

dynamic_cast<AbstractClass*>(ptrA)->anyMethod();

1

据我可以从你的代码OtherClass::anyMethod()看到的不是一个虚拟的和已经实施。它应该像你描述的那样工作,如果你将其定义为virtual

0

我认为你的第二种情况的声明是: OtherClass * ptrA;而不是AbstractClass * ptrA; 如果您声明为第一种情况,则不存在任何问题,因为该方法是虚拟的,但如果声明为OtherClass,则编译器将不会找到虚拟并且不使用vtble而绑定到此方法的地址。