C++面向对象(学习笔记系列之一)

C++面向对象(学习笔记系列之一)

C++ 的类与对象:

一、类是c++的核心特性,即用户定义的类型
类用于指定对象的形式,它包含了数据表示法和用于处理数据的方法。
类中的数据和方法称为类的成员。(函数在一个类中被称为类的成员)
C++类的定义:
类定义是以关键字class开头,后面跟上类的名称。
类定义后主体在{}内{}的结尾要用;
{}内应使用public、private、protected关键字确定类成员的访问属性
定义C++对象:
对象根据类创建
声明类的对象,就像声明基本类型的变量一样
每个对象都有各自的数据成员
访问数据成员:
使用直接成员访问运算符()来访问类的对象的公共数据成员
但是私有的和受保护的成员不能使用直接访问运算符()来直接访问//如何访问//
类与对象详解:
1.类的成员函数:类的成员函数是指那些把定义和原型写在类定义内部的函数;
类的成员函数是类的一个成员它可以操作类的任意对象、可以访问对象中的所有成员;
范围解析运算符 ::详解:
https://blog.csdn.net/long0801/article/details/77993250?ops_request_misc=%7B%22request%5Fid%22%3A%22158270727819724811805737%22%2C%22scm%22%3A%2220140713.130056874…%22%7D&request_id=158270727819724811805737&biz_id=0&utm_source=distribute.pc_search_result.none-task
成员函数可以在类定义内部定义也可以使用范围解析运算符::来定义
在类定义中定义的成员函数把函数声明为inline的,即使没有使用inline标识符
2.C++类访问修饰符:关键字public、private、protected称为访问修饰符,成员和类的默认访问修饰符是private。实际操作中,经常在私有区域定义数据,在公有区域定于相关的函数。私有成员变量或者函数在类的外部是不可访问的,甚至是不可查看的。只有类和友元函数可以访问私有成员;保护成员与私有成员基本相似,但是保护成员可以在派生类中访问。
访问修饰符在继承中的特点:private具有最高优先级
3.C++类构造函数与析构函数:类的构造函数是类的一种特殊的成员函数,构造函数的名称与类的名称相同,没有返回值类型、不会返回void。构造函数可用于为默认成员变量设置初始值。构造函数可以带有参数;
析构函数是类的一种特殊成员函数,它会在每次删除所创建的对象时执行;析构函数不会返回任何值,也不能带有任何参数;析构函数有助于在跳出程序(关闭文件、释放内存)前释放资源。
4.拷贝构造函数(拷贝构造、拷贝辅助、析构):三个作用:通过使用另一个同类型的对象来初始化新创建的对象;复制对象,把它作为参数传递给函数;复制对象,并从函数返回这个对象。
如果类带有指针变量并有动态内存分配,则它必须有一个拷贝构造函数。
5.友元函数:类的友元函数定义在类外部(友元不是类的成员),但有权访问类的所有pubilc和private成员。尽管友元函数的原型有在类的定义中出现过,但是友元函数不是成员函数。
6.内联函数:对内联函数的任何修改,都需要重新编译函数的所有客户端;如果想要把一个函数定义为内联函数,需要在函数名前面加关键字inline,
在调用函数之前需要对函数进行定义;在类定义中定义的函数都是内联函数,即使没有使用inline。
7.this指针:每一个对象都可以通过this指针来访问自己的地址;this指针是所有成员函数的隐含参数。因此,在成员函数内部,他可以用来指向调用对象。只有成员函数才有this指针(友元不是类的成员,所以友元函数没有this指针)
8.指向类的指针:一个指向C++类的指针与指向结构的指针类似,访问指向类的指针的成员,需要使用成员访问运算符->就像访问指向结构的指针一样(点运算符“.”和箭头运算符“->”都可以访问成员,其中点运算获取类对象的一个成员,箭头运算符获取指向对象的成员,例如表达式ptr->men等价于(*ptr).men)
https://blog.csdn.net/autocyz/article/details/44498209?ops_request_misc=%7B%22request%5Fid%22%3A%22158281080719726867809306%22%2C%22scm%22%3A%2220140713.130056874…%22%7D&request_id=158281080719726867809306&biz_id=0&utm_source=distribute.pc_search_result.none-task
在使用指针之前,应对指针进行初始化。
9.类的静态成员:(1)静态成员数据:使用关键字static可以把类成员定义为静态的。当我们声明类的成员为静态时。无论创建多少个类的对象,静态成员都只有一个副本;静态成员在类的所有对象中都是共享的。如果不存在其他的初始化语句,在创建第一个对象时,所有的静态数据都会被初始化为零;我们不能把静态成员的初始化放置在类的定义中,但是可以在类的外部通过使用范围解析运算符::来重新声明静态变量,从而对它进行初始化。
(2)静态成员函数:静态成员函数可以把函数与类的任何特定对象独立开来;静态成员函数即使在类对象不存在的情况下也能被调用,静态函数只要使用类名加上范围解析运算符::就可以访问;静态成员函数只能访问静态成员数据、类外部的其他函数和其他静态成员函数;静态成员函数有一个范围,他们不能访问类的this指针。因此我们可以使用静态成员后汉书来判断类的某些对象是否已被创建。
注:静态成员函数与普通成员函数的却别:(1)静态成员函数没有this指针,因此只能访问静态成员(2)静态成员函数没有this指针,普通成员函数有this指针可以访问类中的任意成员。

C++继承:

一、继承允许我们依据一个基类来定义派生类,这样做可以使创建和维护应用程序更加容易;同时。也达到了重用代码的功能和提高执行效率的效果。当创建一个类时,不需要重新编写新的数据成员和成员函数。只需指定新建的类(派生类)继承了一个已有的类(基类)的成员。(继承代表了 is a 关系;;例如,哺乳动物是动物,狗是哺乳动物,则狗是动物)
二、基类和派生类:一个类可以派生自多个基类(因此,父类与子类的称呼并不合适)这意味着,派生类可以从多个基类继承数据和函数。定义一个派生类,我们使用一个类派生列表来指定基类。
类派生列表以一个或多个基类命名,形式如下:
class derived-class:access-specifier(默认private) base-class,access-specifier base-class
(各个基类之间用逗号分隔)
派生类可以访问基类中所有的非私有成员。
一个派生类继承了所有的基类方法,但下列情况除外:
(1)基类的构造函数、析构函数、拷贝构造函数
(2)基类的重载运算符与基类的友元函数
三、公有(public)继承:当一个类派生自公有基类时,基类的public成员也是派生类的public成员;基类的protected成员也是派生类的protected成员;基类的private成员不能直接被派生类访问,但是可以通过调用基类的public和protected成员来访问。
四、多继承:多继承是指一个派生类继承了多个基类的特性。

C++重载运算符和重载函数:

一、C++允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载。重载声明是指一个与之前已经在该作用域内声明过的函数或方法有相同名称的声明,但是他们的参数列表和定义(实现)不同。
重载决策:选择合适的重载函数或重载运算符的过程。
二、函数重载:在同一个作用域内可以声明几个功能类似的同名函数,但是这些同名函数的形式参数,即参数的个数类型或者顺序必须不同。而且不能仅通过返回类型的不同来重载函数。
形参与实参的辨析:
https://blog.csdn.net/qq_43752613/article/details/85582115
三、运算符重载:我们可以重定义或者重载大部分C++内置的运算符,这样我们就可以使用自定义类型的运算符。重载的运算符是带有特殊名称的函数,函数名的构成(operator 要重载的运算符)。与其他函数一样,重载运算符有一个返回类型和一个参数列表。
大多数的重载运算符可以被定义为普通的非成员函数或者被定义为类成员函数。
四、可重载运算符与不可重载运算符:
可重载运算符:双目运算符、单目运算符、关系运算符、逻辑运算符与位运算符、自增自减运算符、赋值运算符、空间申请与释放
不可重载运算符:成员访问运算符(->除外)、作用域运算符、长度运算符、条件运算符、预处理运算符
五、输入输出运算符重载:C++能够使用流提取运算符>>来输入、流插入运算符>>来输出内置的数据类型。我们可以重载>>与<<来操作对象等用户自定义的数据类型。此时,我们需要把运算符重载函数声明为类的友元函数,这样我们就可以不用创建对象而直接调用函数。
六、成员访问运算符重载:
类成员访问运算符(->)可以被重载;它被定义用于为一个类赋予“指针”行为。运算符->必须是一个成员函数。如果使用了->则返回类型必须是指针或者类的对象。(智能指针与容器)
智能指针:
https://blog.csdn.net/Nameseven/article/details/101001462?ops_request_misc=%7B%22request%5Fid%22%3A%22158304370919725219924107%22%2C%22scm%22%3A%2220140713.130056874…%22%7D&request_id=158304370919725219924107&biz_id=0&utm_source=distribute.pc_search_result.none-task
七、C++多态:多态就是指多种形态;当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态;C++多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。
多态的作用:有了多态,就可以有多个不同的类,这些类具有不同实现的函数,函数的参数甚至可以是相同的。
虚函数:虚函数是在基类中使用关键字virtual声明的函数。在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数。
因为我们想要的是在程序中任一点可以根据所调用的对象类型来选择调用函数,这种操作被称为动态链接或者后期绑定。
纯虚函数:把0赋给虚函数

C++数据抽象:

一、数据抽象只表现必要的信息而不呈现细节(只向外界提供关键信息,并隐藏其后台的实现细节)。数据抽象是一种依赖于接口和实现分离的编程技术。就C++编程而言,C++类为数据抽象提供了可能,它们向外界提供了大量用于操作对象数据的公共方法,也就是说,外界实际上并不清楚类的内部实现,例如我们的程序可以调用某种函数,但不要具体指导实现该函数的算法。在C++中,我们使用类来定义我们自己的ADT(抽象数据类型)。
二、访问标签强制对象:在C++中我们使用访问标签来定义类的抽象接口;一个类可以包含0个或多个访问标签。
(1)使用公共标签定义的成员都可以访问该程序的所有部分,一个类型的数据抽象视图是由它的公共成员来定义的。
(2)使用私有标签定义的成员无法访问到使用类的代码,私有部分对使用类型的代码隐藏了实现细节。
访问标签出现的频率没有限制;每个访问标签指定了紧随其后的成员定义的访问级别;指定的访问级别会一直有效,直到遇到下一个访问标签或遇到类主体的关闭右括号为止。
三、数据抽象的好处:
(1)类的内部受到保护,不会因无意的用户级错误导致对象状态受损。
(2)类的实现可能随着时间的推移发生变化以应对需求的变化、或应对那些要求不改变用户级代码的错误报告。
如果只在类的私有部分定义数据成员,编写该类的作者就可以随意更改数据;如果实现发生改变,则只需要检查类的代码,看看这个改变会导致那些影响;如果数据是公有的,则任何直接访问旧表示形式的数据成员的函数都可能受到影响。

C++数据封装:

一、C++程序的两个基本要素:
(1)程序语句(代码):这是程序执行动作的部分,称为函数。
(2)程序数据:数据是程序的信息,会受到程序函数的影响。
“封装”是OOP(面向对象编程)中的把数据和操作数据的函数绑定在一起的一个概念,这样能避免受到外界的干扰和误用,从而确保了安全。C++通过创建类支持封装和数据隐藏(public、private、protected)
二、数据封装与数据抽象:
数据封装是一种把数据和操作数据的函数捆绑在一起的机制。
数据抽象是一种仅向用户暴露接口而把具体的实现细节隐藏起来的机制。
三、设计策略:
通常情况下,我们都会设置类成员状态为private,这样才能保证良好的封装性。者通常应用于数据成员,也同样适用于所有成员,包括虚函数。
四、虚函数:
C++中,虚函数可以为private,并且可以被基类覆盖,但是派生类不能调用基类的private虚函数;虚函数的重载性和它声明的权限无关。
VPTR:
https://blog.csdn.net/xiaoyink/article/details/79441203?ops_request_misc=%7B%22request%5Fid%22%3A%22158320769719724846429342%22%2C%22scm%22%3A%2220140713.130056874…%22%7D&request_id=158320769719724846429342&biz_id=0&utm_source=distribute.pc_search_result.none-task
一个成员函数被定义为private属性,表示其只能被当前类的其他成员函数或者友元函数访问;但是virtual强调的是基类的成员函数可以在子类中被重写,因为重写之时并没有与基类发生任何的调用关系,因此重写是被允许的。

C++接口:

一、C++接口描述了类的行为和功能,而不需要完成类的特定实现。C++接口是使用抽象类来实现的;如果类中至少至少有一个函数被声明为纯虚函数,则这个类就是抽象类。纯虚函数是通过在声明在使用“=0”来指定的。抽象类与数据抽象互不混淆,数据抽象是把实现细节与数据分离开的概念。
二、设计抽象类的目的为了给其他类提供一个可以继承的适当的基类。抽象类不能被用于实例化对象,他只能作为接口使用。如果试图实例化一个抽象类的对象,会导致编译错误。因此,如果一个抽象类的子类需要被实例化,则必须实现虚函数,也即C++支持使用抽象类声明接口。如果没有在派生类中重写虚构函数,就试图实例化该类的对象,则会导致编译错误。
三、可用于实例化对象的类称为具体类
//学自菜鸟教程,仅供个人学习使用//

猜你喜欢

转载自blog.csdn.net/BJTUYBYUAN/article/details/104630983