C++基础——继承

文章目录

  • 1 概述
  • 2 继承的基本语法
  • 3 继承方式
  • 4 继承中的构造和析构顺序
  • 5 继承同名成员处理
  • 6 继承同名静态成员处理方式
  • 7 多继承
  • 8 菱形继承
  • 9 QA

1 概述

继承是面型对象的三大特征之一
继承用于描述类于类之间的从属关系,被继承的类称为基类或父类,继承的类称为子类

2 继承的基本语法

#include 
using namespace std;

class Father {
public:
    int getNum() {
        return m_num;
    }
public:
    int m_num = 10;
};

class Son :public Father {

};

int main() {
    Son son;
    cout << son.m_num << endl;
    cout << son.getNum() << endl;
    return 0;
}

输出

10
10

继承之后,子类拥有了父类的属性和行为。需要注意的是,子类是否拥有父类的属性和行为,还决定于继承方式和父类的访问权限。

3 继承方式

继承访问分为三种

  • 公共继承
  • 保护继承
  • 私有继承

语法
class 子类 :继承方式 父类

#include 

using namespace std;

class Father {
private:
    int m_A;
protected:
    int m_B;
public:
    int m_C;
};

void test() {
    Father father;
    // father.m_A; //不能访问private成员
    // father.m_B; //不能访问protected成员
    father.m_C;
}

// 公共继承
class Son1 : public Father {
public:
    void func() {
        // m_A; //不可访问private成员
        m_B;
        m_C;
    }
};

void test1() {
    Son1 son;
    // son.m_A; //不可访问private成员
    // son.m_B; //不可访问protected成员
    son.m_C;
}

// 保护继承
class Son2 : protected Father {
public:
    void func() {
        // m_A; //不可访问private成员
        m_B;
        m_C;
    }
};

void test2() {
    Son2 son;
    // son.m_A; //不可访问private成员
    // son.m_B; //不可访问protected成员
    // son.m_C; //不可访问public成员
}

// 私有继承
class Son3 : private Father {
public:
    void func() {
        // m_A; //不可访问private成员
        m_B;
        m_C;
    }
};

void test3() {
    Son2 son;
    // son.m_A; //不可访问private成员
    // son.m_B; //不可访问protected成员
    // son.m_C; //不可访问public成员
}

C++有三种权限控制

  • private 只能在本类中的函数中访问,不能被对象访问
  • protected 可以在本类和子类中的函数中访问,不能被对象访问
  • public 可以在本类、派生类中的函数访问,也可在其他函数中被对象访问

三种继承后:

  • 公共继承:基类的public成员,在子类中为public;基类的protected成员在子类中为protected;基类中的private成员不可访问
  • 保护继承:基类中的public和protected成员在子类中都为protected;基类中的private成员不可访问
  • 私有继承:基类中的public和protected成员在子类中都为private;基类中的private成员不可访问

4 继承中的构造和析构顺序

#include 

using namespace std;

class Father {
public:
    Father() {
        cout << "father constructor" << endl;
    }
    ~Father() {
        cout << "father deconstructor" << endl;
    }
};

class Son : public Father {
public:
    Son() {
        cout << "son constructor" << endl;
    }
    ~Son() {
        cout << "son deconstructor" << endl;
    }
};
void test() {
    Son son;
}

int main() {
    test();
    return 0;
}

构造顺序:先父类后子类
析构顺序:先子类后父类
析构和构造刚好相反

5 继承同名成员处理

  • 访问子类同名成员,直接访问
  • 访问父类同名成员,需要加作用域
#include 

using namespace std;

class Father {
public:
    Father() {
        m_A = 100;
    }

    void func() {
        cout << "Father func()" << endl;
    }

    void func(int a) {
        cout << "Father func(int a)" << endl;
    }

public:
    int m_A;
};

class Son : public Father {
public:
    Son() {
        m_A = 200;
    }

    void func() {
        cout << "Son func()" << endl;
    }

public:
    int m_A;
};

void test() {
    Son son;
    cout << son.m_A << endl;
    cout << son.Father::m_A << endl;
    son.func();
    son.Father::func();
    son.Father::func(10);
}

int main() {
    test();
    return 0;
}

输出:

200
100
Son func()
Father func()
Father func(int a)

子类如果存在和父类同名的成员,则子类会覆盖父类的同名成员。用子类对象调用同名成员,访问的是子类自有的成员,如果要访问父类被覆盖的成员,需要加父类作用域。

6 继承同名静态成员处理方式

静态成员不属于对象,属于类,所以静态成员是不被子类继承的

#include 

using namespace std;

class Father {
public:
    void func() {
        cout << "Father func()" << endl;
    }

    void func(int a) {
        cout << "Father func(int a)" << endl;
    }

public:
    static int m_A;
};

int Father::m_A = 100;

class Son : public Father {
public:
    void func() {
        cout << "Father func()" << endl;
    }

    void func(int a) {
        cout << "Father func(int a)" << endl;
    }

public:
    static int m_A;
};

int Son::m_A = 200;

void test() {
    Son son;
    cout << son.m_A << endl;
    cout << son.Father::m_A << endl;

    cout << Father::m_A << endl;
    cout << Son::m_A << endl;
}

int main() {
    test();
    return 0;
}

输出:

200
100
100
200

与成员变量的覆盖规则相同,使用作用域访问。
除了使用对象访问外,也可以通过类名访问。

7 多继承

C++允许一个类继承多个类
多继承可能存在多个父类有同名函数,需要加作用域区分
实际开发中不建议使用多继承

#include 

using namespace std;

class Base1 {
public:
    Base1() {
        m_A = 200;
    }

public:
    int m_A;
};

class Base2 {
public:
    Base2() {
        m_A = 100;
    }

public:
    int m_A;
};

class Son : public Base1, public Base2 {

};

void test() {
    Son son;
    // cout << son.m_A << endl; //编译错误,无法定位访问哪个父类的成员
    cout << son.Base1::m_A << endl;
    cout << son.Base2::m_A << endl;
}

int main() {
    test();
    return 0;
}
200
100

同名成员需要添加作用域,否则编译出错,无法定位具体调用哪一个。

8 菱形继承

菱形继承就是一个基类,两个派生类继承基类,当前类同时继承两个派生类,形成一个菱形。

#include 

using namespace std;

class Base {
public:
    int m_A;
};

class SubBase1 : public Base {
};

class SubBase2 : public Base {
};

class Son : public SubBase1, public SubBase2 {
};

int main() {
    Son son;
    // son.m_A = 200; //产生歧义
    son.SubBase1::m_A = 100;
    son.SubBase2::m_A = 200;

    cout << son.SubBase1::m_A << endl;
    cout << son.SubBase2::m_A << endl;
    return 0;
}

输出:

100
200

菱形继承主要问题是会有重复数据,导致资源浪费,可以采用虚继承解决菱形继承问题

9 QA

private在子类不可访问,那是否继承了呢?

int main() {
    cout << sizeof(Father) << endl;
    cout << sizeof(Son1) << endl;
    cout << sizeof(Son2) << endl;
    cout << sizeof(Son3) << endl;
}

打印类大小

12
12
12
12

说明private也是继承了的,只是无法访问

你可能感兴趣的:(C++语言,c++,java,jvm)