首页 > 代码库 > C++基础复习
C++基础复习
1.Object-C也是面向对象的语言;
2.#include<iostream> //#include是一个预处理指令
3.using namespace std; //std是命名空间,using决定了该源程序中的代码可以不用指定命名空间名为std
4.const 常量只能读,不能修改,并且定义时必须初始化;
5.由低精度向高精度转化不会影响精度,由低精度向高精度转化会影响精度;
函数重载:函数名相同,函数的参数不同,通过参数的判断,调用不同的同名函数,实现函数的功能;
所以函数重载中,进行函数调用时是由实参转化为形参是按从低精度向高精度转化的;
6.函数默认参数:默认参数的定义顺序为自右向左,即一个参数设定了缺省值(默认值)时,其右边的参数必须都要有缺省值;
默认参数函数调用时,遵循函数调用顺序,自左向右逐个匹配。
7.引用:
例如:
int a;
int &ra = a;
声明引用时必须同时对其进行初始化;
不能创建一个指向引用的指针;
不能声明一个数组的引用;
引用作为形参:在内存中不会产生实参的副本,它是直接对实参进行操作的。 //使用引用传递参数,节省了空间
8.常引用:
int a;
const int &ra = a;
ra = 1;//错误,没有权限
a = 1;//正确
定义函数:void f(const int &ra); //保证在函数内部,ra的值不会被改变
9.函数形参与调用时实参的关系。。?
10.类的访问限制:
private : 默认类型 //只能被本类的成员函数使用。
public
protected
11.类:
成员函数实现放在类的定义中,则默认为内联函数;
函数实现放在类外,可加inline关键字定义为内联函数。
如: inline void Cloack::showClock(){cout<<"I am clock!"<<endl;}
每个类的对象都有一份自己的数据空间,但是类的成员函数只存储一份,为所有的对象所共有。
类的成员函数中可以访问本类对象的私有成员。
12.构造函数与析构函数:
构造函数:为对象申请空间以及初始化赋值。 ///////
//具有初始化列表的构造函数:Clock(int h,int m,int s): hour(h),minute(m){second=s;}
写在初始化列表与函数体中的区别为:写在初始化列表中认为:简单变量的定义并初始化
写在函数体中:简单变量的先定义再赋值;故前者效率较高。
13.析构函数与构造函数的执行顺序是相反的。析构函数严格按照此相反顺序执行!!应该是压栈处理的缘故。
派生类类的构造函数在定义对象时调用,顺序为先是基类的构造函数,然后是对象成员的构造函数,最后是该派生类本身的构造函数。
14.拷贝构造函数分为浅拷贝与深拷贝。
浅拷贝只是复制对象空间,而深拷贝将复制对象空间以及之外申请的额外资源(一般是堆空间)。
浅拷贝会出现析构时的错误。可能会对同一个内存资源进行两次释放删除,导致错误的出现。
拷贝构造的参数必须是类对象的引用,否则会造成拷贝构造函数的递归调用。因为不使用引用,在调用时,首先将实参copy给形参,
然后再对形参进行操作。最后形成对拷贝构造函数递归的调用。最好使用const类型的表示引用的形参。--》考虑实参是怎么向形参传递值得??
15.每个非静态的成员函数均有一个隐含的指针变量this。//是一个指针,表示对象的地址。
16.类的静态数据成员,只有一份,存储在全局区。所有的对象共享该静态数据成员。
类的静态数据成员,必须在类外进行初始化。它的生命周期是与类相同的,不依赖于对象的存在而存在。
17.sizeof(数组名):数组名本身是一个地址常量。
以 char arr[10];为例
则 数组名 的类型为:char * const //是一个地址常量
其另一个语义是:数组对象。 所以对数组名取地址,意思即是对数组对象取地址,其结果的值就是数组名本身的地址常量值。
所以不能说数组名是一个指针。
当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。
18.静态成员函数只能访问静态成员数据或静态成员函数,不能访问非静态、的成员函数或成员数据。
其不具有this指针,又是所有对象共享的,又没有this指针,所以其只能访问静态的成员数据或者成员函数。
19.const数据成员,其必须在构造函数的初始化列表中列出,以对其进行初始化。
const成员函数不能调用非const函数,但是能够使用非const得成员数据,只要不修改它就行。
20.友元函数,可以是非成员函数。能够访问类的私有、保护、公有的成员数据。(但是通过对象名进行访问)
友元类:类中的所有成员函数均是另一个类的友元函数。
关于类与对象的空间分配问题!
21.注意重载流插入运算符<<的方法:应该将运算符重载函数写为非成员函数,例如:友元函数
ostream& operator <<(ostream& out,const 类名& a); //注意返回值为 ostream 的类型。
目的是能够使 cout<<a<<b<<endl; //正常的连续输出。
22.函数返回引用时,返回的不能是临时变量,必须是全局变量。因为返回临时变量,释放了的时候,引用所指向的就是空了。
继承:
23.派生类的构造函数:
派生类不继承基类的构造函数与析构函数。故,需要自己添加相应基类的构造函数。
当派生类中有对象成员时,其构造函数的初始化列表中应该有对对象成员的初始化。此时构造函数的顺序为:先是基类,然后是对象成员,最后是
自身。
多重继承:构造函数顺序为派生类对基类的继承顺序。
24.派生类的析构函数:
继承与多重继承的析构函数,严格的与构造函数的执行顺序是相反的。
25.基类与子类中数据成员同名进行访问,会出现二义性。
方法:用类名限定符, 类名::成员名
26.虚基类:
多重继承,如果2个父类有共同的基类。则会对基类进行两次的构造。一个父类一次,造成空间的开销。浪费了对象的空间。
虚基类:在派生类继承基类时定义。 使内存中只建立基类的一个副本。
calss 派生类名: virtual [继承方式] 基类名
基类的构造函数也只会在最后的派生类中继承一次。
27.派生类能够赋值给基类,反之则不可以。赋值后基类的类型还是基类,只能使用基类的成员数据与成员函数。
28.关于创建对象的两种方法:使用new 与 不使用new,有一定的区别。使用 new 进行创建时,应该用delete释放空间。只有使用delete时
才会调用析构函数对对象进行析构。且使用new时,如果创建的对象是一个无参数的对象,那么所new的类名的后边也应该加上括号,但是直接
定义对象,就不需要加括号。
例如:对于类Student 则应该为; Student * pstu = new Student(); // Student stu;
多态: 关键词:虚函数 抽象类 纯虚函数
29.多态分为静态多态与动态多态。
静态多态指程序编译时系统就能确定是哪个函数。 通过函数重载来实现。
动态多态是指程序运行时系统才能确定运行的是哪个函数。动态多态是通过虚函数(virtual function)实现的。
29.虚函数:
虚函数的作用是:允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或者基类引用来访问这个同名函数。
虚函数:系统会根据运行时对象所属的类来寻找与之匹配的函数。
关联:分为了静态关联和动态关联。
虚函数具有继承性,即在基类中将函数声明为虚函数后,无论在继承类中进行重写时是否将函数声明为虚函数,该函数均是虚函数。
虚函数调用时应通过基类的指针或者引用进行调用。
30.虚析构函数:
将基类的析构函数写成虚函数。其作用是,当用基类的指针或者引用来删除派生类时,能够调用派生类的析构函数。否则只是调用基类的
析构函数。
但是不能将构造函数写为虚函数。 // 原因是,写成虚函数的目的是实现动态绑定,即是在运行的时候使函数与对象的类型进行绑定,来判断
该函数是否执行,以及按何种方式执行。而在运行构造函数时,对象还没有生成,此时,无法实现动态绑定。所以构造函数不能写为虚函数,
构造函数内部也不能调用虚函数。
31.纯虚函数:
没有函数体,起作用就是为其派生类保留一个函数的名字,以便派生类对它的行为进行重新定义。
virtual 函数类型 函数名(参数列表) = 0;
32.抽象类:
含有纯虚函数的类为抽象类。抽象类只能作为基类,无法进行实例化,即不能创建一个抽象类的对象,但是可以声明一个抽象类的指针和引用。
面向对象的三大特征:封装(encapsulation)、继承(inheritance)、多态(polymorphism)。
模板:
33.函数模板:函数模板被调用时编译器才产生代码。 用实参的类型替换掉形参类型,这个过程叫做函数模板的实例化。
template<class T>
T min(T a,T b)
{
return (a<b)?a:b;
}
34.函数模板的特化:使模板能够处理一种特殊情况下的问题。
template<> 返回类型 函数名(参数列表)
{函数体}
35.类模板:
类模板的的实例化,在程序中显式的指出。
类模板只有实例化后才能产生具体的代码。
特化类模板:必须在前面加上 template <>
//或许你也可以说,你所面临的这一切都不是问题。
其他问题:
sizeof 求一个空类的结果为1。
原因为:所谓类的实例化就是在内存中分配一块地址,每个实例在内存中都有独一无二的地址。同样空类也会被实例化,所以编译器会给空类隐含的添加一个字节,这样空类实例化之后就有了独一无二的地址了。所以空类的sizeof为1。C++编译器不允许对象为零长度。试想一个长度为0的对象在内存中怎么存放?怎么获取它的地址?为了避免这种情况,C++强制给这种类插入一个缺省成员,长度为1。如果有自定义的变量,变量将取代这个缺省成员。