继承(注意菱形继承)

继承(Inheritance) 是面向对象编程中的一个核心概念,允许你基于现有的类创建新类,从而促进代码的复用和扩展。

在 C++ 中,继承是通过 classstruct 来实现的。子类可以继承父类的 成员变量成员函数,甚至可以覆盖父类的方法。


基本语法

class 基类 {
public:
    // 基类的成员
};

class 派生类 : public 基类 {
public:
    // 派生类的成员
};

说明

  • 基类(Base Class):被继承的类。
  • 派生类(Derived Class):继承基类并扩展其功能的类。
  • public 是访问控制符,它指定了派生类对基类成员的访问权限。

示例:简单继承

#include <iostream>
using namespace std;

// 基类
class Animal {
public:
    void eat() {
        cout << "This animal eats food." << endl;
    }
};

// 派生类
class Dog : public Animal {
public:
    void bark() {
        cout << "The dog barks." << endl;
    }
};

int main() {
    Dog dog;
    dog.eat();  // 继承自基类 Animal
    dog.bark(); // 派生类 Dog 特有的方法
    return 0;
}

输出:

This animal eats food.
The dog barks.

解释:

  • Dog 类继承了 Animal 类,所以 Dog 对象可以调用 Animal 类中的 eat 方法。
  • Dog 类还可以定义自己的成员函数,例如 bark

继承的访问控制:public, protected, private

继承时可以指定不同的访问控制符,控制父类成员在子类中的访问权限。

  1. public 继承(最常见):

    • 基类的 publicprotected 成员在派生类中保持相同的访问权限。
    • 基类的 private 成员不可访问。
    class Base {
    public:
        int public_var;
    protected:
        int protected_var;
    private:
        int private_var;
    };
    
    class Derived : public Base {
        void func() {
            public_var = 1;    // OK
            protected_var = 2; // OK
            private_var = 3;   // Error
        }
    };
    
  2. protected 继承

    • 基类的 publicprotected 成员变为派生类中的 protected 成员。
    • 基类的 private 成员不可访问。
    class Derived : protected Base {
        void func() {
            public_var = 1;    // OK
            protected_var = 2; // OK
            private_var = 3;   // Error
        }
    };
    
  3. private 继承

    • 基类的 publicprotected 成员都变为派生类中的 private 成员。
    • 基类的 private 成员不可访问。
    class Derived : private Base {
        void func() {
            public_var = 1;    // OK
            protected_var = 2; // OK
            private_var = 3;   // Error
        }
    };
    

构造函数与继承

派生类会自动调用基类的构造函数。可以显式调用基类的构造函数来初始化基类部分。

示例:带构造函数的继承

#include <iostream>
using namespace std;

class Animal {
public:
    Animal(string n) {
        name = n;
        cout << "Animal Constructor: " << name << endl;
    }
    void eat() {
        cout << name << " is eating." << endl;
    }
private:
    string name;
};

class Dog : public Animal {
public:
    Dog(string n) : Animal(n) {  // 显式调用基类构造函数
        cout << "Dog Constructor: " << n << endl;
    }
};

int main() {
    Dog dog("Buddy");
    dog.eat();
    return 0;
}

输出:

Animal Constructor: Buddy
Dog Constructor: Buddy
Buddy is eating.

说明:

  • Dog 类通过 : Animal(n) 显式调用了基类 Animal 的构造函数。

虚拟继承(Virtual Inheritance)

虚拟继承是用来解决 菱形继承问题 的,避免多重继承时出现 二义性

菱形继承问题

如果一个类继承了两个父类,而这两个父类又有一个共同的基类,那么这个共同基类会被继承两次。虚拟继承解决了这个问题。

示例:虚拟继承

#include <iostream>
using namespace std;

class A {
public:
    A() {
        cout << "Constructor A" << endl;
    }
};

class B : virtual public A {
public:
    B() {
        cout << "Constructor B" << endl;
    }
};

class C : virtual public A {
public:
    C() {
        cout << "Constructor C" << endl;
    }
};

class D : public B, public C {
public:
    D() {
        cout << "Constructor D" << endl;
    }
};

int main() {
    D d;
    return 0;
}

输出:

Constructor A
Constructor B
Constructor C
Constructor D

说明:

  • 由于 BC 都是虚拟继承自 A,所以 A 的构造函数只会被调用一次,避免了菱形继承带来的重复调用问题。

总结

  • 继承 是面向对象编程的一个重要概念,它使得我们能够复用和扩展已有的类。
  • C++ 支持 单继承多继承,通过 public, protected, private 来控制继承的访问权限。
  • 构造函数 通过显式调用父类的构造函数来初始化基类部分。
  • 虚拟继承 解决了多重继承中的菱形继承问题。

你是正在实现一个多态系统,还是需要对某个继承问题进行优化?我可以帮你详细解析!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值