C ++中的私有继承以最少的例子。

时间:2018-01-14 15:27:07

标签: c++ inheritance

因为我觉得C ++中的受保护的私有继承感觉不太舒服,所以我搜索了它并得出了这个stackoverflow答案:Difference between private, public, and protected inheritance。 太好了!我想,让我们试一试。所以我编写了一个小例子程序来测试它,并将exptected输出写为注释。

 class Person{
   public: virtual void publicInterface() {}
   protected: virtual void protectedInterface() {}
   private: virtual void privateInterface() {}
    };

    class Professor : public Person  {};
    class Teacher : protected Person { 
    public: void teachPublic(){publicInterface();}
    public: void teachProtected(){protectedInterface();}
    public: void teachPrivate(){privateInterface();}        // not compiling
    };
    class Student : private Person {
    public: void learnPublic(){publicInterface();}
    public: void learnProtected(){protectedInterface();} 
    public: void learnPrivate(){privateInterface();}        // not compiling
    };
    int main()
    {
        Person* p = new Person();       // ok is-a
    Person* pro = new Professor();  // ok    is-a
        Person* t = new Teacher();      // not compiling! No is-a relat.
        Person* s = new Student();      // not compiling! No is-a
        Teacher* t2 = new Teacher();        // ok
        Student* s2 = new Student();    // ok
        pro->publicInterface();     // ok
    t2->publicInterface();      // not compiling
    s2->publicInterface();      // not compiling
    t2->teachPublic();          // ok
    t2->teachProtected();           // ok
    t2->teachPrivate();         // not compiling
    s2->learnPublic();          // ok
    s2->learnProtected();       // not compiling   <-- compiles, but why?
    s2->learnPrivate();         // not compiling
    }

运行它确实完全符合我的预期。但是,最后一行似乎是编译的 - 这有点没有从所描述的私有继承行为中删除。

有人知道为什么要编译吗?

3 个答案:

答案 0 :(得分:0)

方法learnProtected是公开的。因此它可以从外面打电话#34; (即通过s2)。

方法protectedInterface受到保护,这意味着它只能由Person的成员和朋友或来自Person的任何类的成员访问。 Student类派生自Person,因此learnProtected可以调用protectedInterface

它私有地继承自Person这一事实只会影响Base类和成员的外部可见性。无论使用哪种继承(私有,受保护,公共),Student本身都可以访问Person的任何公共或受保护成员。

答案 1 :(得分:0)

是的,谢谢HolyBlackCat!

我现在有一个例子,它向我解释了私有继承的行为:

    class Person{
    public: virtual void publicInterface() {}
    protected: virtual void protectedInterface() {}
    private: virtual void privateInterface() {}
};
class Professor : public Person  {};
class Teacher : protected Person { 
public: void teachPublic(){publicInterface();}
void teachProtected(){protectedInterface();}    // ok!
    void teachPrivate(){privateInterface();}        // not compiling
};
class Student : private Person {
public: void learnPublic(){publicInterface();}
void learnProtected(){protectedInterface();}    // ok!
void learnPrivate(){privateInterface();}        // not compiling
};
class TA : public Teacher {
public: void correctExercises(){publicInterface();}
};
class Child : public Student {
public: void play(){publicInterface();}  //NOT working, since we priva
};
int main()
{
    Person* p = new Person();       // ok is-a
Person* pro = new Professor();  // ok    is-a
    Person* t = new Teacher();      // not compiling! No is-a relat.
    Person* s = new Student();      // not compiling! No is-a
    Teacher* t2 = new Teacher();        // ok
    Student* s2 = new Student();    // ok
    pro->publicInterface();     // ok
t2->publicInterface();      // not compiling
s2->publicInterface();      // not compiling
t2->teachPublic();          // ok
t2->teachProtected();           // ok
t2->teachPrivate();         // not compiling
s2->learnPublic();          // ok
s2->learnProtected();           // ok! learnProteted is public
s2->learnPrivate();         // not compiling
TA* ta = new TA();          // ok 
Child* c = new Child();     // ok
ta->correctExercises(); // ok
c->play();              // ok however call inside play not ok!
}

但我仍然觉得这很模糊......在现实世界中没有人能真正想出这样的设计,对吗?

答案 2 :(得分:-2)

函数Person :: learnProtected()在Student类中不可见,因此当您声明Student :: learnProtected()时,编译器将其理解为不覆盖声明。

您可以确保添加约束&#34;覆盖&#34;对于Student :: learnProtected(),当函数没有覆盖父虚函数时,编译器将显示错误:

const dbHandler = require('dbHandler');

app.get('/blogs/all',function(req,res,next){    

    Blog.find({},dbHandler(res));

});

这会导致编译错误:

  

C3668&#39;学生:: learnProtected&#39;:方法,使用覆盖说明符&#39;覆盖&#39;没有覆盖任何基类方法ConsoleApplication3