5分钟掌握C++中的三种继承方式

public 方式继承

基类成员对派生类的可见性对派生类来说,基类的公有成员和保护成员可见,基类的公有成员和保护成员作为派生类的成员时,它们都保持原有的状态;基类的私有成员不可见,基类的私有成员仍然是私有的,派生类不可访问基类中的私有成员。

基类成员对派生类对象的可见性对派生类对象来说,基类的公有成员是可见的,其他成员是不可见的。

所以,在公有继承时,派生类的对象可以访问基类中的公有成员,派生类的成员函数可以访问基类中的公有成员和保护成员。

简单来说,派生类能访问基类的public, protected成员,继承过来权限不变,派生类对象只能访问基类public成员。

测试代码如下:

class A
{
private:
    int m_data1;
    void print1() { cout << "private print1" << endl; }
protected:
    int m_data2;
    void print2() { cout << "protected print2" << endl; }
public:
    A(int x = 1, int y = 2, int z = 3) : m_data1(x), m_data2(y), m_data3(z) {}
    int m_data3;
    void print3() { cout << "protected print3" << endl; }
};

class B : public A
{
public:
    void test_public() {
        cout << m_data3 << endl;
        print3();
    }
    void test_protected() {
        cout << m_data2 << endl;
        print2();
    }
    void test_private() {
        // 下面两行编译不过,B类内无法访问父类的私有成员
        // cout << m_data1 << endl;  
        // print1();
    }
};


int main(int argc, char const* argv[])
{
    B b;
    b.test_public();
    b.test_protected();
    b.test_private();
    cout << b.m_data3 << endl;
    // cout << b.m_data2 << endl;  // 编译不过,子类对象无法访问父类protected的成员
    // cout << b.m_data1 << endl;  // 编译不过,子类对象无法访问父类private的成员
    return 0;
}

private 方式继承

基类成员对其对象的可见性与一般类及其对象的可见性相同,公有成员可见,其他成员不可见

基类成员对派生类的可见性对派生类来说,基类的公有成员和保护成员是可见的,基类的公有成员和保护成员都作为派生类的私有成员,并且不能被这个派生类的子类所访问;基类的私有成员是不可见的,派生类不可访问基类中的私有成员。

基类成员对派生类对象的可见性对派生类对象来说,基类的所有成员都是不可见的。所以,在私有继承时,基类的成员只能由直接派生类访问,而无法再往下继承。

简单来说派生类可以访问基类的public, protected成员,继承过来之后变成自己私有的。 派生类的对象啥都不能访问。

class A
{
private:
    int m_data1;
    void print1() { cout << "private print1" << endl; }
protected:
    int m_data2;
    void print2() { cout << "protected print2" << endl; }
public:
    A(int x = 1, int y = 2, int z = 3) : m_data1(x), m_data2(y), m_data3(z) {}
    int m_data3;
    void print3() { cout << "protected print3" << endl; }
};

class B : private A
{
public:
    void test_public() {
        cout << m_data3 << endl;
        print3();
    }
    void test_protected() {
        cout << m_data2 << endl;
        print2();
    }
    void test_private() {
        // 下面两行编译不过,B类内无法访问父类的私有成员
        // cout << m_data1 << endl;  
        // print1();
    }
};


int main(int argc, char const* argv[])
{
    B b;
    b.test_public();
    b.test_protected();
    b.test_private();
    // cout << b.m_data3 << endl;  // // 编译不过,子类对象无法访问父类public的成员
    // cout << b.m_data2 << endl;  // 编译不过,子类对象无法访问父类protected的成员
    // cout << b.m_data1 << endl;  // 编译不过,子类对象无法访问父类private的成员
    return 0;
}

protected 方式继承

基类成员对派生类的可见性对派生类来说,基类的公有成员和保护成员是可见的,基类的公有成员和保护成员都作为派生类的保护成员,并且不能被这个派生类的子类的对象所访问,但可以被派生类的子类所访问;基类的私有成员是不可见的,派生类不可访问基类中的私有成员。

基类成员对派生类对象的可见性对派生类对象来说,基类的所有成员都是不可见的。

简单来说: 派生类可以访问基类的public, protected,继承过来都变成了protected,派生类对象啥都不能访问。

总结

对于这三种方式继承的派生类来说: 都能访问基类的public, protected 成员;

public 的方式继承到派生类,这些成员的权限和在基类里的权限保持一致;
protected方式继承到派生类,成员的权限都变为protected;
private 方式继承到派生类,成员的权限都变为private;

对于三种方式派生类的对象来说: 只有public的方式继承后,派生来的对象只能访问基类的public成员,protected和private方式继承,派生类的对象都不可以访问父类的成员。

例: 请考虑标记为A到J的语句在编译时可能出现的情况。

#include<iostream>
#include<cstdio>

class Parent
{
public:
    Parent(int var=-1) {
        m_nPub = var;
        m_nPtd = var;
        m_bPrt = var;
    }
    int m_nPub;
protected:
    int m_nPtd;
private:
    int m_nPrt;
};

class Child1 : public Parent
{
public:
    int GetPub() { return m_nPub; }
    int GetPtd() { return m_nPtd; }
    int GetPrt() { return m_nPrt; }
    // A
};

class Child2 : protected Parent
{
public:
    int GetPub() { return m_nPub; }
    int GetPtd() { return m_nPtd; }
    int GetPrt() { return m_nPrt; }
    // B
};

class Child3 : private Parent
{
public:
    int GetPub() { return m_nPub; }
    int GetPtd() { return m_nPtd; }
    int GetPrt() { return m_nPrt; }
    // C
};

int main(int argc, char const *argv[])
{
    Child1 cd1;
    Child2 cd2;
    Child3 cd3;

    int nVar = 0;

    // public inherited
    cd1.m_nPub = nVar; // D
    cd1.m_nPtd = nVar; // E
    nVar = cd1.GetPtd(); // F

    // protected inherited
    cd2.m_nPub = nVar; // G
    nVar = cd2.GetPtd(); // H

    // private inherited
    cd3.m_nPub = nVar; // I
    nVar = cd3.GetPtd();  // J
    return 0;
}

A, B, C都错误,因为 m_nPrt 是父类的private变量,子类不能访问。

D正确。 cdl是公有继承,可以访问并改变父类的公有变量。

E 错误。 m_nPtd 是父类 Parent 的保护变量,不可以被公有继承的 cdl 访问, 更不可以被修改。 虽然 m_nPtd 是父类 Parent 的保护变量,经过公有继承后, m_nPtd 在子类中依然是protected, 而子类的对象cdl是不能访问自身的protected成员,只能访问public成员。

F正确。派生类内可以访问父类的保护变量。

G错误。cd2是保护继承的,派生类对象不能访问父类成员。

H正确。派生类内可以访问父类的保护变量。

I错误。cd2是私有继承的,派生类对象不能访问父类成员。

J正确。派生类内可以访问父类的保护变量。

你搞懂了吗?码字不易,点个赞再走吧!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353

推荐阅读更多精彩内容