C++继承顺序

白柒 / 2024-01-18 / 原文

派生类可以访问基类中所有的非私有成员。因此基类成员如果不想被派生类的成员函数访问,则应在基类中声明为 private。

我们可以根据访问权限总结出不同的访问类型,如下所示:

访问 public protected private
同一个类 yes yes yes
派生类 yes yes no
外部的类 yes no no

一个派生类继承了所有的基类方法,但下列情况除外:

  1. 基类的构造函数、析构函数和拷贝构造函数。
  2. 基类的重载运算符。
  3. 基类的友元函数。
#include <iostream>
using namespace std;
class Base{
    public:
        int a;
        int b;
    Base(int a=0, int b=0){
        this->a = a;
        this->b = b;
        cout<<"Constructor Base::Base("<<a<<","<<b<<")"<<endl;
    }
    ~Base(){
        cout<<"destructor Base..."<<endl;
    }
    int product(){
        return this->a * this->b;
    }
    friend std::ostream &operator<<(std::ostream &os, const Base &obj){
        os<<"Base: a="<<obj.a<<",b="<<obj.b;
        return os;
    }
};

class Derived: public Base{
    public:
        int c;
    // 继承Base类,会首先自动调用Base的构造函数
    // 然后再去执行子类的构造函数
    Derived(int c):Base(c-2, c-1), c(c){
        // 这个a来自父类Base,在父类构造函数之后修改
        this->a += 3;
        cout<<"constructor Derived("<<c<<")"<<endl;

    }
    ~Derived(){
        cout<<"destructor Derived("<<c<<")"<<endl;

    }
    int product(){
        // 子类调用父类的product
        return Base::product() * c;
    }
    friend std::ostream &operator<<(std::ostream &os, const Derived &obj){
        // 
        os<<static_cast<const Base&>(obj) << endl;
        os<<"Derived: c="<<obj.c;
        return os;
    }
};

int main(int argc, const char** argv) {
    Base base(1,2);
    cout<<base<<endl;
    int r = base.product();
    cout<<r<<endl;
    cout<<"------------------"<<endl;

    Derived derive(5);
    // 会调用Base(0, 1)
    cout<<derive<<endl;
    cout<<"product"<<derive.product()<<endl;

    return 0;
}