C ++和抽象类中的继承

时间:2011-01-24 17:46:22

标签: c++ class inheritance abstract

我在正确处理覆盖抽象类的方法时遇到问题 在我的类层次结构中。 我会试着解释一下:

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的解决方案?

7 个答案:

答案 0 :(得分:5)

你为什么不这样做:

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

那应该可以解决你的问题

答案 1 :(得分:2)

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

答案 2 :(得分:2)

我认为,如果您要在OtherClassA中覆盖的B中的方法不是虚拟的,则覆盖不是隐式的。

我相信有一种方法可以明确地覆盖这些功能,看一下。

答案 3 :(得分:1)

DeadMGs答案当然是正确的。但是,如果您无法更改OtherClass Methode(例如,它来自第三方lib),您可能想尝试这样做:

下方示例中的ptrAptrB类型的指针是OtherClassAbstractClass吗?

如果他们是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

我犯了两个错误:

  1. 在我的真实代码中(不是之前发布的简化版)我忘了声明虚拟 函数foo()

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

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