C++初级杂记

C++初级杂记

(申明:仅为C++一些知识点的零散摘要和浅析,不涉及具体代码和很深入的剖析)

C++:
抽象、封装、继承、多态(继承、多态:面向对象核心)

C++默认方法(6个)
构造函数
拷贝构造函数
赋值语句(=的重载)
析构函数
普通对象取地址(&的重载)
const对象取地址(const对象&的重载)

1 类的定义与对象的创建
0.作用域限定符:public;protected;private
1.作用域解析运算符:::
2.方法的外部实现:返回值 类名::函数名(参数){}
3.成员访问运算符:.(只有公有成员才能在对象外访问)

2 this指针
//方法中区分 当前是在操作哪个对象的数据
实质为当前对象的地址
编译过程
1.解析类名
2.识别数据成员
3.识别并改写函数(函数参数 插入(当前类类型 *const) this指针)

const指针
int a = 10;
const int *p;	//*p为常量,即指针p所指向的对象不能通过p修改(const在*左边)
int * const p;	//p为常量,即指针p所指向的对象通过p修改(const在*右边)
const int * const p;
//*p和p都为常量,即不能通过指针p修改其所指向的对象;且指针p所指向的对象不能改变(只能读取其指向对象的值)

3 构造函数和析构函数

	3.1 构造函数的定义和使用
		1.函数名与类名一致
		2.无函数返回类型说明
		3.仅在对象被创建时自动调用一次
		4.可以重载,调用时根据参数列表选择其中一个
		5.类中类外均可定义
		6.如果没有构造函数,编译器自动生成一个缺省构造函数;如果有构造函数,则不会自动生成!
		  构造函数无参或参数均有缺省值,编译器都认为时缺省构造函数;缺省构造函数只能有一个
对象使用无参构造:
Test t;	//Test t();错误:被认为是函数声明
构造函数的3个作用
1.构造对象
2.初始化对象
3.类型转换(隐式)	//产生临时对象!
	explicit关键字:显式---修饰构造函数,禁止隐式类型转换
-----------------------------------------------------------------------------
	3.2 析构函数的定义
一个对象的生命周期结束时,C++也自动调用一个函数注销该对象并进行善后工作,
这个特殊的成员函数即析构函数(destructor):
1.构函数名与类名相同,但在前面加上字符‘~’,如
	~CGoods()。
2.析构函数无函数返回类型;不带任何参数。
3.一个类有且只有一个析构函数,这与构造函数不同。析构函数可以缺省。
4.对象注销时,系统自动调用析构函数。

4 引用和拷贝构造函数
4.1 引用(又称别名)
变量、指针、数组、const变量 引用
4.2 拷贝构造函数
函数名与类名一致,参数为该类类型的const引用
调用时机:(本质都是用类对同类对象初始化)
1.用类对同类对象初始化时
2.函数参数为类时(无名临时对象)
3.函数返回值为类时(无名临时对象)
4.3 赋值语句

5.函数的调用优化
1.返回无名临时对象:
return Test(value); //没有类名;不同于Test xxx(value);
2.引用传值
3.引用返回(注意返回对象的 生存周期)

6 深拷贝与浅拷贝
类中的数据成员包含指针;一般需要重新编写:
拷贝构造函数 和 赋值语句
默认的函数不能完成工作;会产生:浅拷贝和深拷贝的后果

默认拷贝构造函数
浅拷贝:只拷贝了指针的指向
深拷贝:重新分配空间,并拷贝指针指向

默认赋值语句
浅赋值:只对指针进行简单赋值
深赋值:重新申请空间,并拷贝指针指向
	1.是否自己给自己赋值
	2.指针是否已有指向(有则释放,指向NULL)
	3.重新申请空间;拷贝内容
	4.返回this引用

7 运算符的重载
定义运算符重载函数的一般格式:
返回值类型 类名::operator重载的运算符(参数表)
{……}
operator是关键字,它与重载的运算符一起构成函数名。

1.运算符重载函数的函数名必须为关键字operator加一个合法的运算符。在调用该函数时,将右操作数作为函数的实参。
2.当用类的成员函数实现运算符的重载时,运算符重载函数的参数(当为双目运算符时)为一个或(当为单目运算符时)没有。
	运算符的左操作数一定是对象,因为重载的运算符是该对象的成员函数,而右操作数是该函数的参数。	
3.单目运算符“++”和“--”存在前置与后置问题。
	前置“++”格式为:
		返回类型  类名::operator++(){……}
	而后置“++”格式为:
		返回类型  类名::operator++(int){……}
		后置“++”中的参数int仅用作区分,并无实际意义,可以给一个变量名,也可以不给变量名。

8 友元
friend
友元函数和友元类

不是类的成员,能访问类的私用部分
不受访问限定符限制

9 静态成员
static
静态方法 静态数据(不含this指针)

静态数据
在类外初始化;可直接通过类名访问
一个类的所有对象所公有;不属于任何具体的对象

静态方法
静态方法只能调用静态数据和方法;普通方法可调用静态方法(含const this指针)
---------------------------------------------
const 
常方法:不能对类的数据成员做修改
void print()const ==>void print(const Test * const this)

10 模板
1-7章

1.函数模板
编译器会根据模板 通过实参演绎或指定的参数类型生成相应类型的 模板函数
模板声明
template <typename Type1,typename Type2>

2.类模板
所有成员函数都是模板函数,在类外实现以模板声明开头;必须指明类型标识

11 动态内存分配
静态内存分配 栈区
动态内存分配 堆区

new delete 
1.无需进行地址类型的转换;
2.无需判断是否返回地址是否为 NULL ;
3.数组类型需指定[size]
4.申请同时可以初始化

new运算符:		1.malloc 	2.Constructor
delete运算符:	1.destroy 	2.free

new 的三种形式
	
	内存泄漏检测#include <vld.h>

	1.new operator	//new操作符:1.operator new(只负责开辟空间) 2.Constructor
	2.operator new	//操作符new:只负责开辟空间	
	3.placement new	//定位new:可以显式调用构造函数
		new(p,偏移量)类型(初始值)

	new的重载
	返回类型:void*  参数类型:size_t //unsigned int
	1.new operator
		void* operator new(size_t sz){}
	3.placement new
		void* operator new(size_t sz,int *d,int pos){}

12.继承与多态

1.继承访问属性
	继承属性 public protected private(默认 private)
	含义:子类的 【继承类型】部分 继承 父类除构造和析构函数之外的所有内容 
	
	1.子类会继承父类的 除构造和析构函数之外的所有内容
	2.子类必须通过共有方法 访问父类的私有部分(private)
	3.子类可直接 访问父类的保护部分(protected)
	
	对象只能直接访问共有部分(public)

2.派生类的析构函数和构造函数

	(1)派生类的构造函数的定义形式为:

		派生类名::派生类名(参数总表):基类名1(参数表1)《,基类名2(参数表2),……,基类名n(参数表n)》,
										《成员对象名1(成员对象参数表1),……,成员对象名m(成员对象参数表m)》{
			……//派生类新增成员的初始化;
		} //所列出的成员对象名全部为新增成员对象的名字
			
		派生类构造函数各部分的执行次序为: 
		1.调用基类构造函数,按它们在派生类定义的先后顺序,顺序调用。 
		2.调用成员对象的构造函数,按它们在类定义中声明的先后顺序,顺序调用。
		3.派生类的构造函数体中的操作。
	
		*在派生类构造函数中,只要基类不是使用缺省构造函数都要显式给出基类名和参数表。
	
	(2)析构函数的功能是作善后工作。
		析构函数各部分执行次序与构造函数相反,首先对派生类新增一般成员析构,
		然后对新增对象成员析构,最后对基类成员析构。

3.钻石继承和虚基类
	virtual(只用于类的成员函数的申明)
	虚基类--->虚拟继承--->钻石继承
	1.不同父类有相同名称的数据成员,用访问限定符::区分
	2.不同父类有相同名称的数据成员,但只继承一份数据:使用虚拟继承
	3.派生类对象创建:构造顺序:虚基类--->非虚基类--->成员对象--->派生类本身

4.同名隐藏和赋值兼容	
	同名隐藏:派生类同名函数会隐藏所有的基类同名函数
	赋值兼容:(向上转换,派生类对象隐含一个基类对象)
			1.派生类的对象可以赋值给基类的对象
			2.派生类的对象的地址可以赋给其基类的指针变量
			3.派生类对象可以初始化基类的引用

13.多态性与虚函数
(1)虚函数
虚函数是一个类的成员函数,定义格式如下:
virtual 返回类型 函数名(参数表)
当某一个类的一个类成员函数被定义为虚函数,
则由该类派生出来的所有派生类中,该函数始终保持虚函数的特征。

派生类中重新定义虚函数(overriding a virtual function,亦译作超载或覆盖)时,
不必加关键字virtual。

1.派生类中定义虚函数必须与基类中的虚函数同名外,还必须同参数表,
	同返回类型。否则被认为是重载,而不是虚函数。
	如基类中返回基类指针,派生类中返回派生类指针是允许的,这是一个例外。
2.只有类的成员函数才能说明为虚函数。这是因为虚函数仅适用于有继承关系的类对象。
3.静态成员函数,是所有同一类对象共有,不受限于某个对象,不能作为虚函数。
4.一个类对象的静态和动态类型是相同的,实现动态多态性时,
	必须使用基类类型的指针变量或引用,使该指针指向该基类的不同派生类的对象,
	并通过该指针指向虚函数,才能实现动态的多态性。
5.内联函数每个对象一个拷贝,无映射关系,不能作为虚函数。
6.析构函数可定义为虚函数,构造函数不能定义虚函数,因为在调用构造函数时对象还没有完成实例化。
	在基类中及其派生类中都动态分配的内存空间时,必须把析构函数定义为虚函数,实现撤消对象时的多态性。
7.函数执行速度要稍慢一些。为了实现多态性,每一个派生类中均要保存相应虚函数的入口地址表,
	函数的调用机制也是间接实现。所以多态性总是要付出一定代价,但通用性是一个更高的目标。
8.如果定义放在类外,virtual只能加在函数声明前面,不能(再)加在函数定义前面。
	正确的定义必须不包括virtual。

(2)多态:离不开 虚拟、继承、使用基类指针和引用
(拓展性:使用相同的接口实现不同的功能)

派生类重写基类的虚方法:同名、同返回类型、同参数列表	
调用时条用派生类的虚方法(同名覆盖)

(3)多态的实现原理(*虚表)
__vfptr—>虚函数的入口地址表 vftable

重载:同一个类,函数名相同,参数表不同
隐藏:基类和派生类,派生类同名函数隐藏基类所有函数
覆盖:基类和派生类,派生类覆盖基类同名虚函数,针对多态

(4)纯虚函数 (占位置,通用抽象接口)
定义纯虚函数的一般格式为:
virtual 返回类型 函数名(参数表)=0;

纯虚函数(pure virtual function)是指被标明为不具体实现的虚拟成员函数。
它用于这样的情况:定义一个基类时,会遇到无法定义基类中虚函数的具体实现,
其实现依赖于不同的派生类。

抽象类:含有纯虚函数的基类是不能用来定义对象的。

1.定义纯虚函数时,不定义虚函数的实现部分。纯虚函数不能调用。
2."=0"表明程序员将不定义该函数,函数声明是为派生类保留一个位置。
	"=0"本质上是将指向函数体的指针定为NULL。
3.在派生类中必须有重新定义的纯虚函数的函数体,这样的派生类才能用来定义对象。	

14.流类体系以及格式控制
(1)格式设置
cout.flags(ios::hex | ios::showbase); //格式设置

(2)流操作子	endl
cout<<hex<<"test"<<endl;	

#include <iomanip.h>
cout<<setw(10)<<"test"<<endl;

15。文件的读写
1.文本文件
2.二进制文件
3.文件的随机读写

	#include <fstream.h>
	(1)创建一个文件流对象
		ifstream;ofstream;
	(2)打开一个文件
		打开模式 ios::out ios::binary ios::in 
	(3)读写文件
	(4)关闭文件

16.文件与对象
对象创建时读取文件数据,初始化对象
对象析构时将数据写入文件,保存数据

17.异常处理
try 尝试运行可能发生异常的代码
throw 抛出异常
catch 捕获异常(按类型捕获;缺省类型(所有类型:catch all)…)

异常规范

自定义异常类

标准异常类

18.标准模板库(STL)
PJ版;SGI版

容器
算法
迭代器
算法->仿函数
容器适配器
空间配置器

类型 template
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值