面向对象设计C++简记

一年前的自学一知半解,本科毕设用python写的导致C++的记忆被清空了。再次学习希望可以有更多的理解,不足之处希望未来的我可以指正。

对象:理解为数据+服务。即自身的动静属性加上对外界的作用。实体

类:是一个概念,包括许多属性。非实体

分装encapsulation:隐藏数据,外界只能访问接口。

继承,多态性

在用c++时添加类,与python不同,声明放在头文件,内容放在另一个文件。

#include "TicketMachine.h"  无括号在当前目录找
#include<iostream>  有括号在系统目录找

构造函数,析构函数~没有类型

public  任何都可以访问

private 只有自己本类的成员函数可以

protect 类自己以及子类访问

class默认私有和struct默认公有,其余无差别

5.1

全局变量:各个模块通用,其他文件用extern声明

静态局部变量:生存周期长,一直存在。但是其作用域仍与局部变量相同,只能在定义该变量的函数内使用该变量。退出该函数后, 尽管该变量还继续存在,但不能使用它。

静态全局变量:当程序只有一个文件模块,其与一般全局变量作用相同; 当程序有多个模块时,静态全局变量的作用范围局限于该模块。

5.2

静态数据成员 

static声明 被该类的所有对象共享,具有静态生存期。

一般在类外初始化,用::指名所属的类,例如:

类内:
class CStudent{
private:

static int Count;//声明了Count变量但未分配内存
}

类外:
int CStudent::Count = 0;//定义静态成员变量,同时初始化为0

静态常量(const/constexpr)可以类内初始化 

静态函数成员

可以直接用类名和作用域调用,处理静态成员(可以直接调用静态成员函数)

可以理解为类的功能,不需要指定的对象

函数前加static即可

friend 友元

可以是友元函数和友元类,声明后代表对方可以访问本类

5.3

常对象  不能被更新 ,只能调用常成员函数。 const 类名 a()

常成员函数  void 域名::函数名() const

常数据成员  只能通过构造函数的成员初始化列表显示进行,如Myclass::Myclass(int i,int j):x(i),a(j),r(x){}。const 类型 a

常引用  效率高又不破坏实参 const 类型 &a

六 数组指针字符串

6.1

数组  有一定顺序关系的若干相同类型变量的集合,组成数组的变量叫元素

常数组  const 类型 a[][] 数组传参的时候传入首地址,用const可以保证原数组不变。

对象数组 

数组名[下标].成员名 访问成员函数

类名 数组名[元素个数]  定义对象数组

6.2

&地址运算符  &a即为a的首地址     *指针运算符 *ptr为ptr指向的内容

指针变量

int i ;

int* ptr = &i ;   ptr为int类型指针变量,只能存int型,指向i 。void类型的指针可以被赋予任何类型的地址。 

static的变量也要用static指针

常指针 

指向常量的指针

int a;
const int* p1 = &a;  // p1是指向常量的指针
int b;
p1 = &b;   //可以,p1可以指向别的
*p1 = 1;   //不行,不能通过常指针改变变量

//a, b自己可以变化

指针类型的常量

int a,b;
int *const p2 = &a;
*p2 = 3;    //可以,相当于给a赋值
p2 = &b     //不行,指针常量不能变化

6.3

指针数组   point *pa[2]   point型指针数组,存放指向point的指针

6.4

用指针作为函数参数  可以改变指针所指向的数据(引用) 或者传数组时使用(可以只传首地址)

如果传指针时不修改,则要声明const,如 void A(const int* p)

传指针和传引用的区别:https://blog.csdn.net/YL970302/article/details/86296428,通常情况下传引用比传指针更加安全

返回值是指针类型的函数  要注意

① 返回值不能是函数里定义的非静态地址

 ② 注意返回的地址是合法的?

函数指针  (指向程序代码储存区,主要实现函数回调)调用函数的时候更灵活,在函数里调函数

定义: 存储类型  数据类型 (*函数指针名)();

对象指针   

对象指针调用成员方法  ptr->getx() 

this指针   隐藏在类的非静态成员函数里

6.5

动态内存分配  new 类型名T(初始化参数)   返回特定类型的指针,用于不确定需要多大空间

例:动态分配数组,double* array = new double[n][3][4]()

释放空间 

delete [] 指针p  释放p所指向的数组

delete 指针p 释放p所指向的内容

动态数组 vector容器    vector<元素类型> 数组对象名(长度)

例如: vector<int> arr(5)

封装任何类型的动态数组,可以自动创建和删除。

对象名不代表首地址,但可以用下标,size可以出尺寸 

常用于储存指针,较大的类对象占用太多内存且要求有默认构造函数(看具体情况)

基于范围的for循环配合auto

 auto:无类型,类型跟着右边走

七 类的继承

7.1  单继承

多继承

 继承之后可以定义同名新成员,隐藏基类的成员

protect成员 继承和public一样,对象调用时和private一样

公有继承 : 基类的public和protect不变,private不可直接访问。派生类成员函数可以访问public和protect;派生类对象只能访问public。

私有继承:基类的public和protect变为private,private不可直接访问。派生类成员函数可以访问基类的public和protect;派生类的对象不能访问任何成员。

保护继承:基类的public和protect变为protect,private不可直接访问。派生类成员函数可以访问基类的public和protect;派生类的对象不能访问任何成员。

向上转型:公有派生类对象在使用上可以被当作基类的对象,反之不可。

7.2

继承时的构造函数  默认情况构造函数不被继承,派生类需要自己定义。写派生类构造函数时,只对新增成员初始化,继承的成员自动调用基类构造函数,但要给基类构造函数传参数。 

可以用 using class::class强制继承基类的构造函数  

单一继承时

当基类中声明有默认构造函数,派生类可以不给基类传参,也可以不声明构造函数。下图把i传给B,j初始化C

 多继承情况

 

 

 复制构造函数  

 不写派生类的复制构造函数,系统默认调用。如果写,一般要给基类传参,但只有一个参数(向上转型)。

比如C::C(const C &c1):B(c1){}

7.3

二义性  基类和派生类有同名函数,基类会被隐藏,想调用可以用类名::函数名调用。

虚基类  当继承函数出现冗余情况,一个函数被继承多次时,用虚基类的方式避免冗余和二义性。这样所有的同名函数都是用虚基类的函数成员。

class B : virtual public Base(){}        

注意:虚基类之下的所有派生类,构造函数都要写给虚基类传参数。建立对象时,只有最远派生类调用虚基类的构造函数,其他基类忽略。

第八章 多态性

8.1  

通过虚函数实现多态  在类定义中声明的同名函数时在前面加 virtual,实现时不用加virtual。如下图中fun函数不再被形参格式限制,而是被参数自身的类控制。(虚函数不能内联,不能是静态)

派生类的虚函数会隐藏基类同名函数的所有其他重载形式

构造函数不能是虚函数,析构函数可以

 

 

 虚析构函数

下图不执行基类析构,只执行了派生类析构,这样会造成危险。所以当基类指针指向派生类对象时,需要把析构函数写成虚函数,即virtual ~Base();

 抽象类  有纯虚函数的类 。 不能定义抽象类的对象

纯虚函数   在基类中没有定义具体操作内容的虚函数,要求派生类自己定义。

virtual 类型 函数名(参数)= 0;

 override 显示覆盖,声明本函数必须覆盖基类虚函数。声明时 virtual void f(int) override;

final 禁止继承  class B final {};

8.2

运算符重载 可以重载为类的非静态成员函数和类外的独立函数(友元)

① 类的非静态成员函数方法

类型 operator 符号 (const 类型 &对象)const

 

 输出自定义对象不能用cout,要重载

重载前置和后置的++ 前置重载函数没有形参,后置需要有一个int形参以作区分,但不传参

 

 ② 类外的独立函数

 九 模板与群体数据

9.1 

编译器根据所给数据推导出模板的具体情况 

函数模板

template <class T>   <>当中的叫类型参数 ,被反推出的具体类型叫类型实参

 类模板

 

 

实例:

 

 

 

9.2

群体 :多个数据元素组成的集合体。分为线性群体和非线性群体,线性群体中元素按照位置排列,可以区分第一第二个,如数组。

线性群体 按照访问元素的方法不同分为直接访问(数组类),顺序访问(链表)和索引访问。

为什么返回引用?

如果返回值是对象的值,就是右值,不能成为左值。如果返回引用,引用是对象的别名,可以通过引用来改变对象从值,因此是左值。

如果这个类需要自己写一个深层的复制构造函数,一般也需要自己写一个重载“=”的函数

指针转换函数不写返回值类型

如下图右侧,编译器无法自动转换array<int>到int,所以需要指针转换运算符

9.3 链表类模板

链表: 链表是动态数据结构,可以用来表示顺序访问的线性群体。由系列结点组成,结点可以在运行时动态生成。

每个结点包括数据域和指向下一个结点的指针。只有指向后继节点的叫单链表

返回被删除的指针,因为不想它释放,直接绕过它会导致再也找不到

结点类模板实例

9.4 栈

暂略

9.5 几个简单的排序查找算法

数组元素比如某个对象中包含多个数据项,关键字比如学生对象中的学号就可以用来识别们就是关键字。

插入排序:将待排序元素按照关键字值的大小插入到适当位置,一个个比较

选择排序:每次从待排序序列中找最小的元素,把它放到末尾

交换排序:起泡排序 :每一轮通过两两比较把最大的数放到最后

二分法查找: 对于排列好的数据,每次查找中间的数,然后二分

十 泛型程序设计与STL库

10.1 泛型程序设计与STL结构

泛型程序设计:将算法从特定的数据结构中抽象出来

可比大小:重载"<",">"       静态数据不能用=赋值,不具备第三个功能

STL标准模板库

op:函数对象,inputlterator输入迭代器,outputlterator输出迭代器

使用STL函数对象,需要包含头文件<functional>

ostream_iterator<int>输出流迭代器  cout输出流对象

10.2 迭代器

迭代器可理解为抽象的指针

cin是输入流对象,与输入流迭代器关联。

第一个是关联到cin的输入流,第二个没给参数,表示指向流结束的迭代器(键盘输入结束,文件结束)。前两个合在一起是范围, 第三个是输出流迭代器

顺序容器:有逻辑上先后的容器

10.3 顺序容器

q1 q2为迭代器当向量中插入新元素,后面的元素整体向后移。如果超出容量则会选择新的储存空间,之前所有的指针,迭代器和引用作废,如果未超出容量,就只有插入位置之后的指针引用迭代器作废

列表一般是为了实现链表,支持双向遍历 

十一  流类库与输入输出

11.1 

概念

程序将流看成文件对象的化身。读———提取,写——插入

输出流

write写二进制文件,seekp写到位置的标记,tellp写道第几个字符

setw和width只对下一次输出管用,其他操纵符大部分都管用

注意打开的文件一定要关闭

向二进制文件输出

write第一个参数是字符型指针,下图中为临时转换的指向起始位置,第二个是大小

向字符串输出

11.2

输入流

不是文件结尾就一直输入

从二进制文件读取数据

payroll文件名,reinterpret_cast转换类型

seekg(3*sizeof(int)) 移动三个int的位置

从字符串输入

输入/输出流

十二 异常处理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值