C/C++之面向对象编程思想3

运算符重载函数运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,简化操作 让已有的运算符 适应不同的数据类型 。
格式:重载+=号运算 ==>operator+=重载+运算符 ==>operator+ ...下面举两个运算符重载例子:
1.重载+号class complex { public: complex() { } double real, imag; complex(double _real, double _imag): real(_real),imag(_imag) { cout << real: << real << imag: << imag << endl; } void print() { cout << real: << real << imag: << imag << endl; } complex(const complex& c) { real = c.real; imag = c.imag; cout << complex copy << endl; } //以全局函数的形式重载 friend complex operator+(const complex& c1, const complex& c2);};complex operator+(const complex& c1, const complex& c2) { complex _c; _c.real = c1.real + c2.real; _c.imag = c1.imag + c2.imag; return _c;}complex func() { complex c(1.0, 2.0); complex c1(2.0, 3.0); complex c2 = c + c1; return c2;}void extendstest::maintest(){ cout << func().real imag += c1.imag; return *this;}complex func() { complex c(1.0, 2.0); complex c1(2.0, 3.0); c += c1; return c;}void extendstest::maintest(){ cout << func().real << endl;};运行结果:real:1 imag:2real:2 imag:3complex copy3运算符重载的限制多数c++运算符都可以重载,重载的运算符不必是成员函数,但必须至少有一个操作数是用户定义的类型。
重载后的运算符必须至少有一个操作数是用户定义的类型 ,防止用户为标准类型重载运算符。如:不能将减法运算符(-)重载为计算两个 double 值的和,而不是它们的差。虽然这种限制将对创造性有所影响,但可以确保程序正常运行。使用运算符时不能违反运算符原来的句法规则 。例如,不能将求模运算符(%)重载成使用一个操作数:int x;time shiva;%x;%shiva;,且不能修改运算符的优先级。不能创建新运算符 。例如,不能定义operator **()函数来表示求幂。4.不能重载下面的运算符。
运算符重载涉及的知识点还是比较多的,后期文章会单独出一期讲解。
多态多态是指:函数调用的多种形态,使用多态可以使得不同的对象去完成同一件事时,产生不同的动作和结果
c++中多态分为 静态多态和动态多态 :
静态多态静态多态的核心思想:对于相关的对象类型,直接实现他们各自的定义,不需要共有基类,甚至可以没任何关系, 只需要各个具体类的实现中要求相同的接口声明,这里的接口称之为隐式接口。客户端把操作这些对象的函数定义为模板,当需要操作什么类型的对象时,直接对模板指定该类型实参即可(或通过实参演绎获得) 。
在模板编程及泛型编程中,是以隐式接口和编译器多态来实现静态多态。
代码如下:
class circle {public: void draw() const{ cout << circle draw << endl; } int z;};class rectangle {public: void draw() const{ cout << rectangle draw << endl; }};templatevoid test(const t& t) { t.draw();}void extendstest::maintest(){ //cout << func().real << endl; circle cir; test(cir); rectangle rec; test(rec);};打印结果:circle drawrectangle draw静态多态本质上就是模板的具现化, 静态多态中的接口调用也叫做隐式接口 ,相对于显示接口由函数的签名式(也就是函数名称、参数类型、返回类型)构成,隐式接口通常由有效表达式组成
动态多态动态多态核心思想:对于相关的对象类型,确定它们之间的一个共同功能集,然后在基类中, 把这些共同的功能声明为多个公共的虚函数接口。各个子类重写这些虚函数, 以完成具体的功能。客户端的代码(操作函数)通过指向基类的引用或指针来操作这些对象, 对虚函数的调用会自动绑定到实际提供的子类对象上去。
动态多态是在运行期完成的,这造就了动态多态机制在处理异质对象集合时的强大威力(当然,也有了一点点性能损失)。
如下代码:
class geometry {public: virtual void draw() const=0;};class circle :public geometry{public: void draw() const{ cout << circle draw << endl; } int z;};class rectangle :public geometry {public: void draw() const{ cout << rectangle draw draw();};打印结果:circle drawrectangle draw//动态多态最吸引人之处在于处理异质对象集合的能力
void drawvec(std::vector { const size_t size = vecgeo.size(); for(size_t i = 0; i draw(); }}动态多态本质上就是面向对象设计中的继承、多态的概念。动态多态中的接口是显式接口(虚函数)
动态多态构成条件 :
1.必须通过基类的指针或者引用调用虚函数。2.被调用的函数必须是虚函数,且子类必须对父类的虚函数进行重写。动态多态实现原理:虚函数表class geometry {public: virtual void draw() const=0;};class circle :public geometry{public: void draw() const{ cout << circle draw << endl; } int z;};class rectangle :public geometry {public: void draw() const{ cout << rectangle draw 对象中的这个指针叫做虚函数表指针,简称虚表指针,虚表指针指向一个虚函数表,简称虚表,每一个含有虚函数的类中都至少有一个虚表指针。
#include using namespace std;//父类class base{public: //虚函数 virtual void func1() { cout << base::func1() << endl; } //虚函数 virtual void func2() { cout << base::func2() << endl; } //普通成员函数 void func3() { cout << base::func3() << endl; }private: int _b = 1;};//子类class derive : public base{public: //重写虚函数func1 virtual void func1() { cout << derive::func1() << endl; }private: int _d = 2;};int main(){ base b; derive d; return 0;}
虚表当中存储的就是虚函数的地址,因为父类当中的func1和func2都是虚函数,所以父类对象b的虚表当中存储的就是虚函数func1和func2的地址。而子类虽然继承了父类的虚函数func1和func2,但是子类对父类的虚函数func1进行了重写,因此,子类对象d的虚表当中存储的是父类的虚函数func2的地址和重写的func1的地址。
这就是为什么虚函数的重写也叫做覆盖,覆盖就是指虚表中虚函数地址的覆盖,重写是语法的叫法,覆盖是原理层的叫法。
虚函数表本质是一个存虚函数指针的指针数组,一般情况下会在这个数组最后放一个nullptr。
当满足多态条件以后,父类的指针或引用调用虚函数时,不是编译时确定的,而是运行时到指向的对象中的虚表中去找对应的虚函数调用,并且引用的底层也是由指针实现,父类在指向子类时会发生切片。 所以指针指向父类的对象,调用的就是父类的虚函数,指向的是子类对象,调用的就是子类的虚函数。
动态多态和静态多态的比较静态多态优点:静态多态是在编译期完成,因此效率高,编译器可以进行优化。 有很强的是适配性和松耦合性。 最重要一点 通过模板编程为c++带来了泛型设计的概念 ,比如强大的stl库
静态多态缺点:由于是模板来实现静态多态,因此 模板的不足也就是静多态的劣势 ,比如调试困难、编译耗时、代码膨胀、编译器支持的兼容性,不能够处理异质对象集合。
动态多态优点:oo设计,对是客观世界的直觉认识;
实现与接口分离,可复用;
处理同一继承体系下异质对象集合的强大威力 ;
动态多态缺点:运行期绑定,导致一定程度的运行时开销 ;
编译器无法对虚函数进行优化;
笨重的类继承体系,对接口的修改影响整个类层次;
不同点:本质不同,静态多态在编译期决定,由模板具现完成,而动态多态在运行期决定,由继承、虚函数实现;
动态多态中接口是显式的,以函数签名为中心,多态通过虚函数在运行期实现,静态多台中接口是隐式的,以有效表达式为中心,多态通过模板具现在编译期完成。
相同点:都能够实现多态性,静态多态/编译期多态、动态多态/运行期多态;
都能够使接口和实现相分离,一个是模板定义接口,类型参数定义实现,一个是基类虚函数定义接口,继承类负责实现;
总结本篇文章详解讲解了c++中的面向对象编程的三大特性:封装,继承以及多态 以及对象编程中模板编程,虚函数,构造函数,析构函数,拷贝构造,操作符重载等知识 , 知识点还是比较多的,需要好好消化下。

2018年中国智能音箱出货量将增长12倍 呈现三足鼎立的格局
SD-WAN是零售业的创收者
对于大多数科技行业来说 2018年是人工智能的清算年
看到这些人工智能实例你有没有惊叹
为什么ARM将会成为物联网时代的的引领者?
C/C++之面向对象编程思想3
MWC2023看点:中兴通讯十大无线新品及方案助力运营商建设全频段融合的5G网络
国内IC产业IDM龙头大厂何时现身
定制版X60基带?!iPhone13或支持低轨卫星通信
浅谈底部填充技术中倒装芯片设计
它曾经也是王者!现在还是王者归来吗?诺基亚9标配6GB内存 预计售价4766元!
!销售/收购/维修HP8753ES网络分析仪HP8753ES
中医医疗机构如何应对药品管理法实施条例征求意见稿的追溯要求
锤子T3、iPhone8、魅族Pro7最新消息:2017下半年只期待这三款旗舰,锤子T3排第一
关于12V电源的浪涌保护小器件方案的介绍
2019年AR和VR整体市场增幅将达到86.9%
电解电容和贴片电容的差异
超值!阿尔法蛋学习手表G6让孩子更加专注学习
线程安全怎么办
技术如何让医生在办公室外进行医疗保健