C++学习之路进阶之面向对象

1.C++基础学习:
https://blog.csdn.net/qxyloveyy/article/details/104261323
2.C++之面向对象:
①左值引用和右值引用
一个引用就是某对象的另一个可选的名字,应用作为别名,实现了对目标对象的名字的绑定,因此必须使用目标对象的原始名字来初始化引用;//T&表示到T的引用;
一个T&的初始化必须是一个类型T的左值名,能够作用在引用上的操作只有初始化,之后的操作全部作用在引用所指向的对象上;
一个引用的值在初始化后就不能改变了,它总是引用它被初始化时所指示的那个对象;要获得一个引用所指向对象的指针,可以取地址&;
引用的一种最直接实现方式是作为一个(常量)指针,在每次使用它时都自动地做间接访问;
const T&//常量引用;
一个const T&的初始式不必是一个左值,甚至可以不是类型T的:
上述情况下,首先,如果需要,将进行转换到T的隐式类型转换,而后将结果存入到一个类型T的临时变量,最后,将此临时变量用做初始式的值;//经常使用const的引用而不是变量的引用作为函数形参;
左值:非临时对象;
右值:临时对像;
右值引用只能绑定到那些临时对象(不绑定通常就要被销毁的对象,或者没有使用者的对象),绑定之后,则可以直接使用而不必销毁临时对象了;
右值引用变量可以引用临时对象,包括其存储和可能的资源(例如打开的文件,锁或者堆存储等),但是右值引用变量本身是左值;
右值引用的常见用法:直接引用右值临时对象,不用声明变量;让函数可以接收右值临时对象作为实参;

②抽象:获得对象
根据需求,捕获与问题相关相关的事物,描述与问题求解相关的该事物数据和行为,忽略那些不重要的内容,得到对应于该事物的软件对象;

③封装:表达
根据需求为对象的数据提供外部访问接口,提供信息隐藏的可能性;

④信息隐藏:保持状态
指不允许外界见到对象内部的信息(内部数据和行为);
使得对象的状态得以保持,只允许通过接口修改对象的状态;

⑤类的定义
是对所有相关对象的共性描述;
每个类描述了创建对象的一个模板或蓝图,每个对象是它的类的一个实列,对于每种属性,对象都有自己的属性值,但共享属性名和操作;

⑥对象的创建和初始化
a)类是创建对象的模板:其数据和函数两类成员描述了所有对象的数据和行为的共性;
类的实例化:使用类创建对象的过程,创建的对象则称为类的实例,使用类创建得到的对象时,会给每个属性设置具体的值,将每一个操作绑定到相应的方法,展现了对象所特有的数据和行为的共性;
创建一个类对象与声明一个内置类型的变量相似,应该根据给定的一个初始式,将对象初始化为一个适当的状态;
有名对象:类名 对象名【初始式】//栈对象或者数据区对象
无名对象:new 类名【初始式】//使用new创建堆对象。返回对象首地址
类名 初始式//创建栈临时对象,即右值对象;
使用类定义创建对象时,系统会:
分配存储:根据数据成员的定义,为对象的数据成员分配存储,同时加载类的方法到代码区(类的方法只会在首次生成对象时加载一次);
初始化构造:根据初始式,调用相应的构造函数进行数据成员初始化,初始化时后续使用时,对象可能会分配到一些资源(堆存储,锁或文件);
初始式:由{}或者()包含的若干初始值,这里的初始值可以是与类对象相同类型的值,也可以是其他类型的值;//int i{10};
空初始式{}表示使用默认值作为初始值,大多数类型都有默认值:整形为0,指针为nullptr,用户定义类型默认值由默认构造函数决定;
b)子类对象的创建
在创建子类对象时,系统会
为对象的数据成员(父类的和子类的)分配存储,加载类的方法(两者的)到代码区;
使用父类的构造函数初始化父类部分数据成员,即先执行父类构造函数初始化列表,然后执行父类构造函数的函数体;
显示调用,在子类构造函数的初始化列表中,添加父类初始式;
隐式调用,省略父类初始式,将调用父类的默认构造函数(此时要求父类有默认构造函数);
根据子类构造函数初始化列表的其余部分,初始化子类部分的数据成员,然后执行子类构造函数的函数体;

⑦对象的销毁
对象是自定义类型的变量,也存在局部,全局,堆和临时等4钟生命期的对象,对象的销毁也遵循这些生命期的规则,对象销毁时,系统通常会执行以下操作:
清理对象所分配的资源(如果对象没有资源,则什么也不做),
回收对象的存储;
堆对象的销毁语法:delete ptr;//ptr中保存的是使用new创建的堆对像的首地址;

⑧构造函数详解
参数构造函数: 只要显示定义了参数或者默认两种构造函数中的一个,系统就不会隐式生成默认构造函数了;
默认构造函数: 调用时不必提供实参的构造函数,它允许用户不提供任何数据来初始化对象,如果类中没有显示声明定义构造函数,系统会自动生成一个隐式/合成默认构造函数来初始化该对象;
如果类中定义了构造函数,则必须显示定义一个默认构造函数,可能是没有形参的构造函数,可能是形参都带有默认值的构造函数;
复制构造函数: 只有在隐式复制构造函数不能满足复制的要求时才会自定义,隐式复制构造函数是浅复制构造函数,对于有资源的类,需要自定义深复制构造函数;
移动构造函数: 移动构造函数用于提供右值源对象的复制优化,他复制对象的非资源成员到目标对象,移动源对像的资源到目标对象;如果没有自定义复制构造函数和移动构造函数时,编译器会自动生成隐式的移动构造函数,其行为类似于隐式的复制构造函数;
移动构造函数需要使用右值引用变量形参来引用临时对象实参,同时需要让临时对象实参能够正常的销毁(析构);
**虚析构函数:**在析构函数前加上关键字virtual,在使用new运算符后做到资源的清理,当基类的析构函数为虚函数时,无论指针指向的是那一个类对像,系统总会采用动态联编,调用正确的析构函数,对该对象进行清理;销毁对象的多态清理操作,需要将其声明为虚函数来提供支持,此时需要将基类的析构操作声明为接口,将其实现为虚析构函数;

⑨泛化
a)链接和关联、自关联及其实现:
链接是对象之间一个现实上或概念上的联系;
关联描述了有着共同的结构和语义的一组链接;
关联通常被实现为从一个对象到另一个对象的引用;//

[class A{
private:
 B b;} 
class B{
private:
 A a;}]//双向关联
class A{
private:
 B b;
}//单向关联
class C{
private:
 C c;
}//自关联

b)多重性:
对于类的关联来说,某个关联端的多重性描述了某个类可以有多个实例与相关类的单个实例相关;多重性的实现:多重性通常会暴露出内建模的隐含假设,最重要的多重性差别存在于"1"和"*"之间;

c)聚合的实现
聚合:两个类之间的简单关联表示了两个同等地位之间的结构关系,它描述了"has a"关系,它也是一种特殊的,表达部分-整体语义的关联;这种聚集是一个语义上的扩展对象,在许多操作中被当作一个单元对待,尽管在物理上它由几个较小的对象组成;
当部分端的多重性为1时:使用单个部分对象指针的方式来实现聚合关系;其他值时:使用部分对象指针数组或者容器的方法来实现聚合关系;

d)组合的实现:
组合:具有更多约束的聚合,一个对象在一个时间内只属于一个组合物,带有非确定多重性的部分可以在组合物之后创建,但一旦创建-除非显示地提前撤销它-它就将随着组合物销毁而一起销毁;
组合关系既可以实现为整体对像的部分对象成员,也可以实现为整体对象的部分对象指针;
如果部分对象比较小,复制代价低,可以将部分对象实现为整体对象的成员,{当部分端的多重性为1时:部分对象以单个成员的方式实现;
为大于1的固定值时:部分对象可以使用成员数组的方式实现;
多重性为可变值时:不建议以成员的方式实现;}
如果部分对象比较大,复制代价高或者要求部分对象与整体对象不能同时创建
{建议使用单指针或指针数组来实现组合关系,将部分对象的指针存储在整体对象中,此时可以创建容纳部分对象的堆存储区,自己进行资源管理;如果多重性为可变值,还需要实现部分对象数目的动态变化;
对于使用了指针的具有资源的类,可以借助移动语义来获得更高的性能;}

e)泛化方式:
泛化属性:形成父类,让子类继承父类的共享属性;
泛化方法(包括操作):形成父类,让子类继承父类的共享方法,抽象了完整语义的行为,包括操作和方法,即行为的接口及其实现东相同;
泛化操作:形成父类,让子类继承父类的共享接口,然后提供子类各自版本的方法,抽象了相似的行为:操作和接口相同,但方法实现不同;

f)泛化的可见性控制:
public基类:父类所有成员的可见性在子类中保持不变,此时父类接口被合并到子类接口;
protected基类:父类公有和保护成员的可见性在子类中都变成保护的,父类私有成员仍然私有,此时父类接口没有合并到子类接口;
private基类:父类所有成员的可见性在子类中都是私有的,此时父类接口没有合并到子类接口;

⑩继承
a)绑定与虚函数:
静态绑定:绑定:将操作与某个类的方法相连接;静态绑定:操作与操作接受者静态类型的方法的连接;对于普通操作来说,不管接受者是任何形式,都将使用静态绑定机制;
动态绑定与虚函数:动态绑定:抽象操作与操作接受者动态类型的方法的连接,由于动态类型只能在运行时指定,因此动态绑定发生在运行时;只有多态变量调用抽象操作时才能使用动态绑定;
动态绑定使用了特殊的虚函数表vtable技术来实现,与静态绑定的技术完全不同;虚函数通过变量名调用时使用静态绑定,通过多态变量调用时使用动态绑定,虚函数才具有动态绑定的能力,是实现多态的关键;

b)抽象操作与接口操作:
抽象操作:泛化子类的相似行为而获得,该类操作将父类子类抽象为一个主题进行操纵,呈现出"多态"的行为,通常声明为纯虚函数;
接口操作:为抽象操作提供了一个默认方法的操作,借口操作仍然作为所有子类的统一接口,要求子类为其提供自己的方法,仍然保持"多态"的行为,接口通常声明为虚函数;
叶子操作:当子类提供关于抽象/接口操作对应方法时,子类所声明的与父类抽象/接口操作签名相同的操作,叶子操作不允许孙子类再提供抽象/接口操作的方法(叶子的含义),如果子类不提供叶子操作,将会继承父类的抽象操作或接口操作;

c)继承实现与接口继承:
实现继承:使得多个子类可以继承父类的属性,行为,操作和接口的完整实现,不用自己再去实现;
接口:一组相关的,可见的操作集合;
接口只定义外部可见的操作,并不包含为操作提供实现的方法,通常,接口的实现由另外的元素(如类和组件)来提供;
类接口:类所有可见操作的集合,类接口通常出现在类定义中;
接口继承:每个子类都以泛化到父类的·操作作为接口,然后自己提供方法作为实现(为了表示·提供了方法,子类必须重新声明对应的叶子操作),从而出现的"1个操作,多个方法"的多态行为;

e)override虚函数修饰符:
override:显示说明子类中的虚函数是继承自基类的,要求做一致性检查;final 虚函数修饰符
final:让类/虚函数成为叶子类/叶子虚函数,不允许继承;

f)虚函数与多态:
多态:对于不同的类来说,相同的操作会有不同的动作,当一个操作的实现方法可以由子类来提供时,则称该操作是"多态的";
抽象操作必定是多态的,叶子操作不是多态的,而且它不允许在派生类中对它进行覆写;
虚函数:使用virtual关键字修饰的操作,用于支持操作多态的机制,泛化得到的抽象操作使用纯虚函数来表示,而子类中提供的叶子操作则实现为完整语义的虚函数;
多态=多态变量+虚函数

谢谢观看,如果本文章对您有用的话,麻烦您点个赞,谢谢!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值