简体   繁体   English

C ++和抽象类中的继承

[英]C++ and inheritance in abstract classes

i have a problem in properly handling method overriding where an abstract class is present inside my classes hierarchy. 我有一个问题,正确处理方法覆盖我的类层次结构中存在抽象类的位置。 I'll try to explain: 我会试着解释一下:

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 example work fine .. the concrete implementation of the AbstractClass method anyMethod will be called at run time. 好的..以前的示例工作正常.. AbstractClass方法的具体实现anyMethod将在运行时调用。 But AbstractClass is derived from another base class which has a method not virtual called 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.

Now , if i try something like that: 现在,如果我尝试这样的事情:

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

What am I misunderstanding? 我有什么误会? Is there any solution for making ptrA and ptrB printing A and B without using cast, typeid, etc? 有没有使用cast,typeid等制作ptrA和ptrB打印A和B的解决方案?

Why don't you do: 你为什么不这样做:

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

That should solve your problems 那应该可以解决你的问题

If anyMethod was declared virtual in the base class to which you have a pointer or reference, it should be looked up virtually and print A and B correctly. 如果anyMethod在具有指针或引用的基类中声明为虚拟,则应该虚拟查找并正确打印A和B. If it wasn't, then there is nothing you can do (beyond changing it to be virtual). 如果不是,那么你无能为力(除了将其改为虚拟)。

I think that if the method in OtherClass that you want to override in A and B is NOT virtual, then the override is not implicit. 我认为如果要在AB覆盖的OtherClass中的方法不是虚拟的,那么覆盖不是隐式的。

I believe there's a way to Explicitly override the functions, look that up. 我相信有一种方法可以明确地覆盖这些功能,看看它。

DeadMGs answer is of course correct. DeadMGs的答案当然是正确的。 But, if you cannot change OtherClass Methode (eg it's from a third party lib) you might want to try this: 但是,如果您无法更改OtherClass Methode(例如,它来自第三方lib),您可能想尝试这样做:

Are the pointers ptrA and ptrB of type OtherClass or AbstractClass in your lower example? 在下面的示例ptrB ,指针是否为类型为OtherClassAbstractClass ptrAptrB

If they are OtherClass I would expect the behaviour you described. 如果它们是OtherClass我会期待你描述的行为。 You could try casting the pointer to AbstractClass then: 您可以尝试将指针强制转换为AbstractClass

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

As far as I can see from your code OtherClass::anyMethod() is not a virtual and already implemented. 从我的代码中可以看出, OtherClass::anyMethod()不是虚拟的,已经实现了。 It should work as you described if you define it as virtual 如果您将其定义为virtual它应该如您所述

I think that your declaration for the second case is: OtherClass* ptrA; 我认为您对第二种情况的声明是:OtherClass * ptrA; and not AbstractClass *ptrA; 而不是AbstractClass * ptrA; if you declared like the first case , there's no problem because the method is virtual,but if you declare as OtherClass , the compiler will not find virtual and bind to the adress of this method without using vtble. 如果您像第一种情况一样声明,则没有问题,因为该方法是虚拟的,但如果您声明为OtherClass,则编译器将找不到虚拟并在不使用vtble的情况下绑定到此方法的地址。

thanks for the answers.. helped me a lot to understand the problem. 谢谢你的答案..帮助我理解了这个问题。 In effect I posted some wrong code, because i was misunderstanding the real problem. 实际上我发布了一些错误的代码,因为我误解了真正的问题。 Anyway, i think i partially solved my problem. 无论如何,我认为我部分解决了我的问题。 Here's the code: 这是代码:

 #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

I was making two errors: 我犯了两个错误:

  1. In my real code (not the simplified version posted before) i forgot to declare virtual the function foo() 在我的真实代码(不是之前发布的简化版本)中我忘了声明虚函数foo()

  2. Even declaring virtual wasn't enough. 甚至宣称虚拟还不够。 In fact all the implementations of that function must be wrapped inside the class Abstract to become visible to the subclasses A and b. 实际上,该函数的所有实现都必须包含在Abstract类中,以便对子类A和b可见。 Otherwise wont't compile. 否则不会编译。

I don't know if it could be a clean solution..in fact that way I need to wrap all foo method signatures. 我不知道它是否可以是一个干净的解决方案。事实上我需要包装所有foo方法签名。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM