Implementing abstract class members in a parent class

后端 未结 4 937
小蘑菇
小蘑菇 2020-12-21 09:07

Is it possible to implement an abstract base class with members inherited from another parent class in C++?

It works in C#, so I tried doing it in C

相关标签:
4条回答
  • 2020-12-21 09:32

    ITalk contains the pure virtual function SayHi(), so if you want to be able to instantiate a class that derives from ITalk that class must implement SayHi().

    class Child : public Parent, public ITalk
    {
    public:
      void SayHi() { std::cout << "Hi!" << std::endl; }
    };
    

    Alternatively, Parent can inherit from ITalk (but not Child) and the code you've posted will work.

    Also, when implementing a base class with virtual functions you must define virtual destructors for those base classes. So ITalk should be:

    class ITalk
    {
    public:
        virtual void SayHi() = 0;
        virtual ~ITalk() {}
    };
    

    If you don't do that the following produces undefined behavior

    ITalk* lChild = new Child();
    lChild->SayHi();
    delete lChild;
    
    0 讨论(0)
  • 2020-12-21 09:33

    Try to use virtual inheritance

    class ITalk
    {
    public:
      virtual void SayHi() = 0;
    };
    
    class Parent: virtual ITalk
    {
    public:
       void SayHi();
    };
    
    class Child : public Parent, public virtual ITalk
    {
    };
    
    void Parent::SayHi()
    {
        std::printf("Hi\n");
    }
    
    0 讨论(0)
  • 2020-12-21 09:37

    It is impossible to be done as you wrote it. The reason behind it is, that every non-static method needs object (this) to operate on (here you don't use any of the object's fields or methods, but that doesn't matter), and this object must be of apropriate type. Parent::sayHi expects this to be of the type Parent, and since ITalk is not related to Parent at all, Parent::sayHi and ITalk::sayHi methods are fundamentaly incompatible.

    C++ is having static type system, so the type must be known at compile time. Languages that use dynamic typing are usually less strict about such constructions, as they can test if object is of apropriate class at function call.

    In C++ the easiest way to implement such behavior would be to simply make Child::sayHi to call Parent::sayHi, as Child is the only class that "knows" where are Parent and ITalk and how should they be related.

    class Child : public Parent, public ITalk
    {
        virtual void sayHi(){ Parent::sayHi(); }
    };
    
    0 讨论(0)
  • 2020-12-21 09:55

    No because what you really have is two base classes without any knowledge of each other.

    Italk    Parent
     / \       / \
      |         |
      +---------+
           |
         Child
    

    If Parent and Italk had two variables named i, there'd be two instances of "i", ITalk::i and Parent::i. To access them you'd have to fully qualify which one you wanted.

    The same is true of methods, lChild has two methods called SayHi and you need to clarify which one you mean when calling SayHi because the multiple inheritance has made it ambiguous.

    You have Parent's SayHi

    lChild->Parent::SayHi();
    

    and Italk's SayHi:

    lChild->ITalk::SayHi(); 
    

    The latter is pure virtual and because its abstract needs to be overridden locally in Child. To satisfy this you'll need to define

    Child::SayHi();
    

    Which would now hide Parent::SayHi() when invoking SayHi without scoping it to the class:

    lChild->SayHi() //parent's now hidden, invoke child's
    

    Of course Child::SayHi() could call Parent::SayHi():

    void Child::SayHi()
    {
         Parent::SayHi();
    }
    

    which would solve your problem.

    0 讨论(0)
提交回复
热议问题