📜  C++继承(1)

📅  最后修改于: 2023-12-03 15:14:04.867000             🧑  作者: Mango

C++继承

继承是C++面向对象编程中的重要概念之一。继承可以让一个类获取另一个类中的数据和方法,从而实现代码的复用和扩展。在本文中,我们将深入探讨C++继承的各种特性和用法。

继承的基本概念

继承是一种从已有类中派生出新类的方式。已有类称为基类(父类),新类称为派生类(子类)。派生类继承了基类的所有成员变量和成员函数,并且可以添加自己的成员变量和成员函数。

在C++中,继承分为三种类型:公有继承、私有继承和保护继承。它们的区别在于继承后派生类对基类成员的访问权限不同。

公有继承

公有继承(public inheritance)是最常见的一种继承方式,在这种方式下,基类的public和protected成员会被派生类继承到,但基类的private成员不能被派生类直接访问。

公有继承的定义方式如下所示:

class Base {
public:
    int public_var;
protected:
    int protected_var;
private:
    int private_var;
};

class Derived : public Base {
public:
    void func() {
        public_var = 1;     // 可以访问基类的public成员
        protected_var = 2;  // 可以访问基类的protected成员
        // private_var = 3;  // 错误!不能访问基类的private成员
    }
};
私有继承

私有继承(private inheritance)是一种保护派生类的方式,在这种方式下,基类的所有成员都会被派生类继承到,但它们都变为了派生类的私有成员,不能被派生类外部直接访问。

私有继承的定义方式如下所示:

class Base {
public:
    int public_var;
protected:
    int protected_var;
private:
    int private_var;
};

class Derived : private Base {
public:
    void func() {
        public_var = 1;     // 错误!不能访问基类的public成员
        protected_var = 2;  // 可以访问基类的protected成员
        // private_var = 3;  // 错误!不能访问基类的private成员
    }
};
保护继承

保护继承(protected inheritance)是介于公有继承和私有继承之间的一种继承方式。在这种方式下,基类的public和protected成员会被派生类继承到,但它们都变为了派生类的保护成员,不能被派生类外部直接访问。

保护继承的定义方式如下所示:

class Base {
public:
    int public_var;
protected:
    int protected_var;
private:
    int private_var;
};

class Derived : protected Base {
public:
    void func() {
        public_var = 1;     // 错误!不能访问基类的public成员
        protected_var = 2;  // 可以访问基类的protected成员
        // private_var = 3;  // 错误!不能访问基类的private成员
    }
};
继承的构造函数和析构函数

当派生类对象创建时,会先调用基类的构造函数,再调用派生类的构造函数。当派生类对象销毁时,会先调用派生类的析构函数,再调用基类的析构函数。在构造函数和析构函数中,我们可以使用特殊的方法调用基类的构造函数和析构函数。

调用基类的构造函数

在派生类的构造函数中,我们可以使用“初始化列表”调用基类的构造函数,该方法的语法如下所示:

Derived::Derived(int arg1, int arg2, int arg3): Base(arg1), member_var_(arg2) {
    // ...
}

以上代码中,我们先调用了Base类的构造函数,以初始化基类的成员变量,然后再使用参数arg2初始化了派生类的成员变量。如果省略了“初始化列表”,则在进入构造函数的函数体之前会先调用基类的默认构造函数进行初始化。

调用基类的析构函数

在派生类的析构函数中,基类的析构函数会自动被调用。我们无需显式调用基类的析构函数。

继承的多态性

继承的多态性指的是基类指针可以在不知道具体派生类类型的情况下指向派生类对象,从而调用派生类的方法。这种做法提高了代码的灵活性和可扩展性。

class Base {
public:
    virtual void func() {
        std::cout << "Base::func()" << std::endl;
    }
};

class Derived1 : public Base {
public:
    void func() {
        std::cout << "Derived1::func()" << std::endl;
    }
};

class Derived2 : public Base {
public:
    void func() {
        std::cout << "Derived2::func()" << std::endl;
    }
};

int main() {
    Base* ptr1 = new Derived1;
    Base* ptr2 = new Derived2;
    ptr1->func();  // 输出:Derived1::func()
    ptr2->func();  // 输出:Derived2::func()
    delete ptr1;
    delete ptr2;
    return 0;
}

在以上代码中,Base类是一个抽象类,其中的虚函数func()被派生类重写了。我们使用基类指针来创建两个不同的派生类对象,然后通过调用基类的虚函数func(),来实现多态性的调用。

总结

在本文中,我们深入探讨了C++继承的各种特性和用法。我们学习了继承的三种类型:公有继承、私有继承和保护继承;了解了如何在构造函数和析构函数中调用基类的构造函数和析构函数;介绍了继承的多态性,以及如何通过基类指针实现对派生类的调用。继承是C++面向对象编程的基石,善于使用继承可以有效提高代码的复用性和灵活性,是每个C++程序员必须掌握的技能之一。