lundi 13 juin 2022

"If the deriving class does not inherit the base class virtually, then all virtual methods must be defined".How to understand that in the right way?

As per the wiki, which says that[emphasise mine]: Note the code snippet in the quotaion is seen here.

Suppose a pure virtual method is defined in the base class. If a deriving class inherits the base class virtually, then the pure virtual method does not need to be defined in that deriving class. However, if the deriving class does not inherit the base class virtually, then all virtual methods must be defined. The code below may be explored interactively here.

#include <string>
#include <iostream>

class A                     { 
    protected: 
        std::string _msg; 
    public:
        A(std::string x): _msg(x) {} 
        void test(){ std::cout<<"hello from A: "<<_msg <<"\n"; } 
        virtual void pure_virtual_test() = 0; }; 

// since B,C inherit A virtually, the pure virtual method >pure_virtual_test doesn't need to be defined 
class B: virtual public A
{ public: B(std::string x):A("b"){}  };  
class C: virtual public A   {
public: C(std::string x):A("c"){}  }; 

// since B,C inherit A virtually, A must be constructed in each child
// however, since D does not inherit B,C virtually, the pure virtual method in A *must be defined* 
class D: public B,C { 
    public: 
        D(std::string x):A("d_a"),B("d_b"),C("d_c"){}
        void pure_virtual_test() override { std::cout<<"pure virtual hello from: "<<_msg <<"\n"; } }; 

// it is not necessary to redefine the pure virtual method after the
parent defines it class E: public D { 
    public: 
    E(std::string x):A("e_a"),D("e_d"){}   };


int main(int argc, char ** argv){
    D d("d");
    d.test(); // hello from A: d_a
    d.pure_virtual_test(); // pure virtual hello from: d_a

    E e("e"); 
    e.test(); // hello from A: e_a
    e.pure_virtual_test(); // pure virtual hello from: e_a 
}

How to understand the statement in bold in the right way?

It seems that if the deriving class(i.e. class B) does not inherit the base class virtually, then virtual methods can be left undefined.Here is my demo code snippet to support what I say:

#include <string>
#include <iostream>

class A                     { 
    protected: 
        std::string _msg; 
    public:
        A(std::string x): _msg(x) {} 
        void test(){ std::cout<<"hello from A: "<<_msg <<"\n"; } 
        virtual void pure_virtual_test() = 0;
}; 

// Attention: B does not inherit A ***virtually***, the pure virtual method pure_virtual_test doesn't need to be defined, either.
class B:  public A   { public: B(std::string x):A("b"){}  }; 


class D: public B { 
    public: 
        D(std::string x):B("d_b"){}
        void pure_virtual_test() override { std::cout<<"pure virtual hello from: "<<_msg <<"\n"; }
}; 

// it is not necessary to redefine the pure virtual method after the parent defines it
class E: public D { 
    public: 
    E(std::string x):D("e_d"){}  
}; 

int main(int argc, char ** argv){
    D d("d"); 
    d.test(); 
    d.pure_virtual_test();

    E e("e"); 
    e.test(); 
    e.pure_virtual_test();
}

Aucun commentaire:

Enregistrer un commentaire