c++封装继承多态原理

文章探讨了C++中的封装概念,如何通过类作为函数参数来调用对象属性和方法。接着讲解了继承的意义,包括private、protected和public的访问控制。多继承的问题,如菱形继承及解决方案——虚继承,以及多态的概念和实现机制,强调了虚函数在多态中的作用。此外,提到了虚析构函数的重要性,用于确保正确销毁子类对象。最后,文章提到了函数的重载、重写和重定义的区别。

【封装】突破c思想,用类做函数参数时调用对象的属性和方法
【继承】意义:复用前人代码
private: 1.该类中的函数、2.其友元函数访问, 不能被任何其他访问,该类的对象也不能访问。

protected:1.该类中的函数、2.子类的函数、 3.其友元函数访问, 但不能被该类的对象访问。

public: 1.该类中的函数、2.子类的函数、 3.其友元函数访问, 4.该类的对象访问。
private 属性不能够被继承。
【多继承】始终存在问题
菱形继承(由继承树变成图,灾难)
1、公共祖先(菱形上部分)解决:虚继承 class A:virtual public B,底层原理:加上virtual关键词后c++编译器会给变量增加属性,类的size会增加一个指针大小vptr
2、两个父类中有相同的属性(菱形下部分),子类无法判断是哪一个父类的属性:类作用域符显式调用

【多态】意义:前人(基类)可以用后人(未来)的代码
父类的指针和引用指向自类,Base * p = child(),当父类和子类中有重名函数,p会调用基类的函数
多态实现:在父类的同名函数前加virtual关键字,实现一种语句多种形态,即父类指针指向不同的子类时,调用对应子类的重名函数。
多态成立条件:1、继承2、虚函数重写3、父类指针(引用)指向子类对象

实现原理:1、类成员(struct)和类函数分开存储,函数隐藏this指针,当用父类指针指向子类对象,调用函数时,传入指针类型的this指针(父类this),通过this指针调用子类函数
2、父类子类对象分别有虚函数表,运行时,动态编译,c++编译器根据指针指向的对象找到虚函数表,并从虚函数表找到函数入口地址
3、vptr分步初始化,子类初始化,先调用父类构造函数,c.vptr指向父类的虚函数表->父类构造函数运行完后c.vptr指向子类的虚函数表
表现:子类初始化过程,在父类构造函数中调用虚函数,调用父类的虚函数

虚函数寻址会降低效率,不要用太多
应用:aop,回调

【虚析构函数】
通过父类指针 指向的子类对象,调用析构函数时不会发生多态,只会按照指针类型调用父类析构函数
虚析构函数能够通过父类指针 把它指向的子类对象的析构函数都执行一遍,释放所有子类资源

【重载 重写 重定义】
一个 类内部 重载,子类无法重载父类
父子两类之间的同名函数,虚函数重写,非虚函数重定义(子类覆盖父类的同名函数)

### 封装 封装原理是隐藏实现细节,将函数和数据包围起来,对数据的访问只能通过可信任的对象和类进行,对不可信的进行信息隐藏。在面向对象编程中,把客观事物封装成抽象的类,类可以把自己的数据和方法只让可信的类或者对象操作,从而使代码模块化,让代码和功能独立[^2]。 使用方法:定义类,将数据成员设为私有(private),通过公有(public)的成员函数来访问和修改这些数据成员。 示例代码如下: ```cpp #include <iostream> class Rectangle { private: double length; double width; public: // 构造函数 Rectangle(double l, double w) : length(l), width(w) {} // 获取面积 double getArea() { return length * width; } }; int main() { Rectangle rect(5, 3); std::cout << "Area: " << rect.getArea() << std::endl; return 0; } ``` ### 继承 继承原理是可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展,其过程是从一般到特殊。通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”“父类”或“超类”。在C++中,一个子类可以继承多个基类,继承概念的实现方式有实现继承、接口继承和可视继承[^2]。 使用方法:使用`class 子类名 : 继承方式 基类名`的语法来实现继承。 示例代码如下: ```cpp #include <iostream> // 基类 class Shape { public: void setWidth(int w) { width = w; } void setHeight(int h) { height = h; } protected: int width; int height; }; // 派生类 class Rectangle : public Shape { public: int getArea() { return (width * height); } }; int main() { Rectangle rect; rect.setWidth(5); rect.setHeight(3); std::cout << "Area: " << rect.getArea() << std::endl; return 0; } ``` ### 多态 多态原理是同一接口可以有不同实现的能力,C++通过函数重载、运算符重载、虚函数和纯虚函数实现多态,可分为静态多态和动态多态。静态多态通过在同一作用域中定义多个同名但参数不同的函数(重载)在编译时实现;动态多态通过派生类重新定义基类中的虚函数(重写)在运行时实现[^3]。 使用方法:静态多态通过函数重载实现,动态多态通过虚函数和重写实现。 示例代码如下: ```cpp #include <iostream> // 基类 class Shape { public: virtual int area() { std::cout << "Parent class area: " << std::endl; return 0; } }; // 派生类 class Rectangle : public Shape { public: int area() { std::cout << "Rectangle class area: " << std::endl; return (width * height); } Rectangle(int w, int h) : width(w), height(h) {} private: int width; int height; }; int main() { Shape* shape; Rectangle rect(5, 3); shape = &rect; shape->area(); return 0; } ``` ### 重载 重载的原理属于静态多态(编译时多态),在同一作用域中定义多个同名但参数不同的函数,编译器根据调用时的参数类型和数量来确定调用哪个函数[^3]。 使用方法:在同一作用域中定义多个同名函数,但参数列表不同。 示例代码如下: ```cpp #include <iostream> int add(int a, int b) { return a + b; } double add(double a, double b) { return a + b; } int main() { std::cout << "Integer addition: " << add(2, 3) << std::endl; std::cout << "Double addition: " << add(2.5, 3.5) << std::endl; return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值