教程 cpp tutorial

继承的基本语法

在 C++ 中,继承是面向对象编程的核心特性之一。通过继承,一个类可以继承另一个类的属性和方法,从而实现代码的复用和扩展。继承的基本语法包括类的声明、继承方式(公有继承、私有继承、保护继承)等。

基本语法

继承的基本语法如下:

cpp
class DerivedClass : accessSpecifier BaseClass {
    // DerivedClass 特有成员和方法
};

`

  • DerivedClass:派生类,继承自基类 BaseClass。
  • BaseClass:基类,提供公共的属性和方法供派生类使用。
  • accessSpecifier:继承的访问控制类型,决定基类成员在派生类中的访问权限,通常是 public、private 或 protected。

继承方式

在 C++ 中,继承的访问控制类型决定了派生类对基类成员的访问权限,常见的继承方式有三种:

  1. 公有继承 (public):派生类可以访问基类的公有和保护成员,但不能访问基类的私有成员。派生类的公有成员保持不变,保护成员保持不变。
  2. 私有继承 (private):派生类将基类的公有和保护成员都变为私有成员。外部无法访问派生类的基类成员,但派生类内部仍可以访问。
  3. 保护继承 (protected):派生类将基类的公有和保护成员变为保护成员。外部无法访问派生类的基类成员,只有派生类及其子类可以访问。

示例:公有继承

cpp
#include <iostream>
using namespace std;

class Animal {
public:
    void speak() {
        cout << "Animal speaks" << endl;
    }
};

class Dog : public Animal {  // 公有继承
public:
    void bark() {
        cout << "Dog barks" << endl;
    }
};

int main() {
    Dog dog;
    dog.speak();  // 派生类可以访问基类的公有成员
    dog.bark();   // 派生类可以访问自己的成员
    return 0;
}

输出:

代码
Animal speaks
Dog barks

在这个例子中,Dog 类通过公有继承继承了 Animal 类的 speak() 方法,因此 Dog 类的对象可以访问 Animal 类的 speak() 方法。

示例:私有继承

cpp
#include <iostream>
using namespace std;

class Animal {
public:
    void speak() {
        cout << "Animal speaks" << endl;
    }
};

class Dog : private Animal {  // 私有继承
public:
    void bark() {
        cout << "Dog barks" << endl;
    }

    void speakDog() {
        speak();  // 派生类内部可以访问基类的公有成员
    }
};

int main() {
    Dog dog;
    dog.bark();  // 访问派生类成员
    dog.speakDog();  // 通过派生类的成员函数访问基类的成员
    // dog.speak();  // 错误:外部无法访问基类的成员
    return 0;
}

输出:

代码
Dog barks
Animal speaks

在私有继承中,Dog 类的对象无法直接访问基类的 speak() 方法,因为基类的公有成员变成了派生类的私有成员。但派生类内部仍然能够访问基类的成员。

示例:保护继承

cpp
#include <iostream>
using namespace std;

class Animal {
public:
    void speak() {
        cout << "Animal speaks" << endl;
    }
};

class Dog : protected Animal {  // 保护继承
public:
    void bark() {
        cout << "Dog barks" << endl;
    }

    void speakDog() {
        speak();  // 派生类内部可以访问基类的公有成员
    }
};

int main() {
    Dog dog;
    dog.bark();  // 访问派生类成员
    dog.speakDog();  // 通过派生类的成员函数访问基类的成员
    // dog.speak();  // 错误:外部无法访问基类的成员
    return 0;
}

输出:

代码
Dog barks
Animal speaks

在保护继承中,Dog 类的对象无法直接访问基类的 speak() 方法,但派生类内部可以访问。

继承中的构造函数和析构函数

在继承中,派生类对象的创建顺序是先调用基类的构造函数,然后调用派生类的构造函数;析构函数的调用顺序是先调用派生类的析构函数,再调用基类的析构函数。

示例:构造函数和析构函数的顺序

cpp
#include <iostream>
using namespace std;

class Base {
public:
    Base() {
        cout << "Base class constructor" << endl;
    }

    ~Base() {
        cout << "Base class destructor" << endl;
    }
};

class Derived : public Base {
public:
    Derived() {
        cout << "Derived class constructor" << endl;
    }

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

int main() {
    Derived derivedObj;
    return 0;
}

输出:

代码
Base class constructor
Derived class constructor
Derived class destructor
Base class destructor

从输出可以看出,先调用基类的构造函数,再调用派生类的构造函数;先调用派生类的析构函数,再调用基类的析构函数。

总结

  • 继承是面向对象编程的重要特性,C++ 中的继承可以通过 public、private 或 protected 关键字来指定继承方式。
  • 公有继承允许派生类访问基类的公有成员,私有继承和保护继承则限制了外部对基类成员的访问。
  • 继承不仅涉及成员的继承,还影响构造函数和析构函数的调用顺序。