本文共 4307 字,大约阅读时间需要 14 分钟。
继承是面向对象编程中实现代码复用的重要机制。它允许在保持基类功能的基础上,通过派生类扩展功能。继承体现了从简单到复杂的层次结构,帮助开发者更好地反映现实世界的事物层次。
示例:
class Person {public: void Print() { cout << "name:" << _name << endl; cout << "age:" << _age << endl; }protected: string _name = "peter"; int _age = 18;};class Student : public Person {protected: int _stuid; // 学号(新增的成员变量)};class Teacher : public Person {protected: int _jobid; // 工号(新增的成员变量)};int main() { Student s; Teacher t; s.Print(); t.Print(); return 0;}
继承带来的作用:
基类和派生类的关系定义如下:
class Person { /*基类定义*/ };class Student : public Person { /*派生类定义*/ };
public
:默认的继承方式,即派生类可以访问基类的所有成员。在C++中,继承时可以指定访问级别:
class Derived : private Base { }; // 派生类不能直接访问基类的private成员class Derived : protected Base { }; // 派生类可以访问基类的protected成员class Derived : public Base { }; // 默认继承方式,派生类可以访问基类的所有成员
访问级别的含义:
private
:派生类无法访问基类的private成员。protected
:派生类可以访问基类的protected成员,但无法访问基类的private成员。public
:派生类可以访问基类的所有成员。基类成员在派生类中的访问方式取决于继承方式:
public
:派生类可以直接访问基类的成员。protected
:派生类可以通过基类的protected成员访问。private
:派生类无法访问基类的private成员。示例:
class Person {protected: string _name; string _sex; int _age;};class Student : public Person {public: int _No; // 学号};void Test() { Person p; Student s; // 派生类对象赋值给基类对象 Person p = s; Person* ptr = &s; Person& rp = s; // 基类指针或引用可以安全地指向派生类对象 ptr = &s; Student* ps = static_cast(ptr); ps->_No = 10; ptr = &p; Student* ps2 = static_cast (ptr); // 可能会导致越界访问 ps2->_No = 10;}
示例:
// 这段代码会报错Student s = p; // 错误,父类对象不能赋值给子类对象
dynamic_cast
来安全地进行类型转换。示例:
class Teacher : public Person {public: int _jobid; // 工号};void Assign() { Person* basePtr = new Person(); Teacher* teacherPtr = new Teacher(); // 安全地将基类指针赋值给派生类指针 teacherPtr = dynamic_cast(basePtr); teacherPtr->_jobid = 123; // 不安全的转换示例 basePtr = new Person(); teacherPtr = static_cast (basePtr); // 可能导致越界访问}
在继承体系中,基类和派生类具有独立的作用域。
Base::member
来直接访问基类的成员。示例:
class A {public: void fun() { cout << "func()" << endl; }};class B : public A {public: void fun(int i) { A::fun(); // 访问基类的成员 cout << "func(int i) - " << i << endl; }};
using Base::Base;
来显式地声明基类成员。通过继承,可以将基类的功能实例化为派生类,同时扩展功能。
示例:
class Animal {public: void Eat() { cout << "动物在吃..." << endl; }};class Dog : public Animal {public: void Bark() { cout << "狗在叫..." << endl; }};int main() { Animal* animal = new Animal(); Dog* dog = new Dog(); animal->Eat(); dog->Eat(); // 调用派生类的Eat函数 dog->Bark(); delete animal; delete dog;}
在支持多态的语言中,继承可以实现运行时绑定。
dynamic_cast
进行安全的类型转换。示例:
class Shape {public: virtual void Draw() = 0;};class Circle : public Shape {public: void Draw() { cout << "画一个圆..." << endl; }};class Triangle : public Shape {public: void Draw() { cout << "画一个三角形..." << endl; }};void DrawShape(Shape* shape) { if (dynamic_cast(shape)) { shape->Draw(); cout << "是圆" << endl; } else if (dynamic_cast (shape)) { shape->Draw(); cout << "是三角形" << endl; }}
using
语句显式地声明基类成员。示例:
class Person {public: void Print() { cout << "name:" << _name << endl; cout << "age:" << _age << endl; }};class Student : public Person {public: using Person::Print; // 显式声明使用基类的Print函数 void NewPrint() { cout << "学号:" << _No << endl; Print(); // 调用基类的Print函数 }};
struct
关键字时,默认使用 public
继承。通过以上内容,我们可以清晰地理解C++继承的核心概念及其应用场景。掌握了继承的规则和注意事项后,可以在实际开发中灵活运用这一强大的工具。
转载地址:http://zagfk.baihongyu.com/