C++——回顾

C++——回顾

一、函数与参数

(1)声明函数时括号里的是形参,如int abc(int a, int b, int c)中的a、b、c就是函数abc的形参,又叫传值参数,若在语句中调用该函数,如z = abc(2, x, y),其中的2、x、y就是与a、b、c对应的实参。在运行时,函数abc在执行前将实参的值通过形参的复制构造函数复制给形参,当函数abc运行结束时,形参类型的析构函数会释放形参,形参的值不会被复制到对应的实参中,因此函数调用不会修改与形参对应的实参的值

(2)模板函数:

template<class T>
T abc(T a, T b, T c){
	return a + b * c; 
}

调用模板函数时会自动将T变为对应的数据类型。

(3)定义函数时void abc(int a, int b, int c)void abc(int &a, int &b, int &c)的区别:
前者如(1)所说,会调用复制构造函数,将实参的值复制给形参;后者中a、b、c称为引用参数,而在z = abc(2, x, y)中调用时,2、x、y这些实参分别是a、b、c的别名,与传值参数不同,在后者被调用时,程序不会复制实参的值,在返回时也不会调用析构函数。节省了传值参数的参数复制操作。返回引用要比返回值要快,因为不用复制对象。

(4)常量引用:T abc(const T&a, const T&b, const T&c),用关键字const指明函数不可修改的引用参数,即该函数不会修改实参。

(5)函数返回的对象被复制到调用环境之中——函数计算出的结果被存储在一个局部的临时变量中,函数结束时,临时变量所占的空间将被释放,其值也不再有效,为了不丢失这个值,要将这个值从临时变量复制到函数的调用环境中。
给函数返回类型增加后缀&,称为引用返回T& abc(int i, T& z),函数中的return z返回形式不会把z的值复制到返回环境中。若在前面加上const,即const T& abc(int i, T& z),称为const引用返回,它在返回调用环境时,必须将值赋给const常量。

(6)一个函数的签名是由这个函数的形参类型以及形参个数确定的,在void abc(int a, int b, int c)中函数abc的签名为(int, int, int)。C++可以定义多个同名函数,但任意两个函数不能拥有同样的签名。定义多个同名函数的机制称为函数重载

二、异常

(1)异常是表示程序出现错误的信息。throw 关键字抛出 运行时异常。

(2)处理异常使用try{} catch{},可以有多个catch块。如果在一个try块之内的代码结束时没有发生异常,catch块就会被忽略。

三、动态存储空间分配

(1)通过操作符new进行存储分配,它的值是一个指针,指向所分配的空间。int *y = new int;为整数分配存储空间,将该空间的指针赋给y,y是对整数指针的引用,*y是对整数本身的引用。若要在该空间中存储整数10可写为:*y = 10;或者iny *y = new int(10);

(2)数组的大小在编译时是未知的,随着函数调用的变化而变化,因此数组只能进行动态存储分配。将数组声明为一个指针:float *x = new float[n];操作符new为n个浮点数分配了存储空间,并返回第一个浮点数空间的指针。对数组元素访问:x[0]、x[1].......x[n-1]

(3)动态存储空间不需要时要删掉,使用delete:delete y;delete []x;

(4)当二维数组的两维大小在编译时都是已知时,可以采用类似创建一维数组的语法来创建二维数组:char c[7][5];;如果在编译时至少有一维的大小是未知的,那么要利用new来创建,假设行数未知:char (*c)[5];c = new char[n][5];;如果行数和列数均未知,那么不可能只调用一次new就能创建这个二维数组,可以把它看作是由若干行所构成的结构,每一行都是一个能用new来创建的一维数组:

template<class T>
bool make2dArray(T ** &x, int numberOfRows, int numberOfCols){
	x = new T *[numberOfRows];//创建行指针
	for(int i = 0; i < numberOfRows; i++){
		x[i] = new int [numberOfCols];
	}
	return true;
}

而在释放空间时要先释放for循环中每一行所分配的空间,然后释放行指针所分配的空间:

void delete2dArray(T ** &x, int numberOfRows){
	for(int i = 0; i < numberOfRows; i++){
		delete [] x[i];
	}
	//删除行指针
	delete [] x;
	x = NULL;
}

四、自有数据类型

(1)C++的类结构:class

class Test{
public:
	Test();//constructor 构造函数————无返回值,指明了创建一个类对象的方法
	~Test();//destructor 析构函数————类对象超出作用域调用该函数来删除对象

	void output() const;
private:

protected:

};

声明类对象时,若初始值个数少于构造函数的参数个数,则会使用缺省值初始化。

Test *test = new Test();

以上代码声明了一个Test类的指针test,调用new操作符创建一个Test对象,并把对象的指针存储在test中。
关键字const指明该函数不会改变调用对象的值,这种函数称为常量函数
成员函数如果不在类声明体内部实现,而在外部实现,必须使用作用域说明符,如Test::Test(){}表示Test类的构造函数,Test::output表示Test类的output成员函数。
在C++中,保留关键字this指向调用对象,*this便是调用对象。return *this使用了返回引用,省去了返回值的复制过程。
如果把数据成员声明为公有成员,有可能会被用户赋给一个无效值,从而导致一些成员函数的结果有误。

(2)因为用户仅仅通过公有部分所提供的接口与Test类进行交互,所以对私有部分的修改不会影响应用程序的正确性,可以通过修改私有部分来修改对Test类对象的数据描述。

(3)非成员函数不能访问类的私有成员,如果要赋予别的类和函数直接访问该类的私有成员,则需要把这些类和函数声明为该类的友元:friendfriend语句总是紧跟在类标题语句之后,函数之前。

(4)一个类A从另一个类B派生,A是派生类,B是基类:class A:class B{};。C++提供了保护性成员protected派生类可以访问基类的保护性成员
用户可以访问的类成员应该是公有的,数据成员永远不要出现在公有部分,它们可以被定义为保护性成员或私有成员,通过成员函数、派生类可以间接访问。修改基类的实现代码时不用修改它的派生类。

(5)在头文件中,文件头加上语句:

#ifndef Test_
#define Test_

在文件尾加上语句:

#endif

代表包含在这组语句之内的代码只编译一次。与#pragma once类似。

(6)异常类:当一个函数的实参值无意义时,要抛出的异常就是这个类型。

五、递归函数

(1)直接递归:函数f中包含了调用f的语句。

(2)间接递归:函数f调用了g,g调用了h,…直至又调用了f。

(3)递归函数分为基础部分(直接定义,不用递归即可求解)和递归部分

(4)每一次调用递归函数,其参数值都比上一次的参数值要小,从而重复调用递归函数使参数值达到基础部分的值。

六、标准模板库

C++标准模板库STL是一个容器、适配器、迭代器、函数对象(也称仿函数)和算法的集合。
详细介绍见【C/C++】STL详解

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wrdoct

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值