我在正确处理覆盖抽象类的方法时遇到问题 在我的类层次结构中。 我会试着解释一下:
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 ..以前的示例工作正常.. AbstractClass的具体实现 方法anyMethod将在运行时调用。 但是AbstractClass是从另一个具有非虚方法的基类派生的 叫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
我误解了什么? 有没有使用cast,typeid等制作ptrA和ptrB打印A和B的解决方案?
答案 0 :(得分:5)
你为什么不这样做:
class OtherClass
{
public:
virtual void anyMethod()
{
cout << "OtherClass";
};
}
那应该可以解决你的问题
答案 1 :(得分:2)
如果在您拥有指针或引用的基类中将anyMethod
声明为虚拟,则应虚拟查找并正确打印A和B.如果不是,那么你无能为力(除了将其改为虚拟)。
答案 2 :(得分:2)
我认为,如果您要在OtherClass
和A
中覆盖的B
中的方法不是虚拟的,则覆盖不是隐式的。
我相信有一种方法可以明确地覆盖这些功能,看一下。
答案 3 :(得分:1)
DeadMGs答案当然是正确的。但是,如果您无法更改OtherClass
Methode(例如,它来自第三方lib),您可能想尝试这样做:
下方示例中的ptrA
或ptrB
类型的指针是OtherClass
和AbstractClass
吗?
如果他们是OtherClass
,我会期待你描述的行为。您可以尝试将指针转换为AbstractClass
然后:
dynamic_cast<AbstractClass*>(ptrA)->anyMethod();
答案 4 :(得分:1)
据我所知,您的代码OtherClass::anyMethod()
不是虚拟的,已经实现了。如果您将其定义为virtual
答案 5 :(得分:0)
我认为您对第二个案件的声明是: OtherClass * ptrA;而不是AbstractClass * ptrA; 如果你像第一种情况一样声明,没有问题,因为该方法是虚拟的,但如果你声明为OtherClass,编译器将不会找到虚拟并绑定到此方法的地址而不使用vtble。
答案 6 :(得分: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
我犯了两个错误:
在我的真实代码中(不是之前发布的简化版)我忘了声明虚拟 函数foo()
即使宣布虚拟还不够。实际上,该函数的所有实现都必须包含在Abstract类中,以便对子类A和b可见。否则就不会编译。
我不知道它是否可以是一个干净的解决方案。事实上我需要包装所有foo方法签名。