1.C++中引用与指针的异同:
相同点:
(1)都可以作为函数的形参,并且效果相同。
不同点:
(1)指针可以有数组,引用不能成为数组的类型。
(2)指针可以指向指针,引用不能引用引用。
(3)void类型可以有指针,但不能有引用。
(4)除非了常指针(char *const name)和指向常量的指针(const char * name)有特殊限制以外,指针没太大的束缚,而引用在初始化后就不能修改了(与 char*const name比较像)。常引用效果跟(const char *const name)一样。
(5)函数返回一个类型的引用,这种函数可以作为左值。
2.C++的结构体可以有函数,C不行。
3.C++的成员初始化列表的意义:在C++中某些类型的成员是不允许在构造函数中赋值语句直接复制的(如引用,常数据成员),但是使用初始化列表就可以。成员初始化列表的初始化顺序并不是构造函数上面的顺序,而是数据成员在类中的声明顺序。
4.不能建议同时使用默认参数和重载,容易出现二义性。
5.析构函数没有参数,不能被重载。
6.析构函数的触发条件:
(1)在主函数结束时;
(2)如果一个对象被定义在一个函数体内,则当这个函数被调用结束时,该对象将释放,析构函数被自动调用;
(3)若一个对象是使用new创建的,在使用delete的时候,会自动调用析构函数。
7.“ int a= new int(9);”是可以的,但是不能直接初始化new创建的数组;
8.调用拷贝构造函数的3种情况:
(1)当用类的一个对象去初始化该类的另一个对象时,拷贝构造函数将会被调用。
(2)当函数的形参是类的对象,在调用函数进行形参和实参结合时,拷贝构造函数将会被调用。
(3)当函数的返回值是类的对象,在函数调用完毕将返回值带回函数调用处时。
9.静态成员初始化应在类外进行,而且在定义对象之前进行。静态成员可以直接用“类名::静态数据成员名”访问。
10.静态成员函数与非静态成员函数的重要的区别是:非静态成员函数有this指针,而静态成员函数没有this指针。
11.静态成员函数不访问非静态数据成员,如果一定要访问非静态数据成员,可以通过对象引用作为形参,来使用。
12.友元函数不是当前类的成员函数,而是独立于当前类的外部函数,但它可以访问该类所有的成员,包括私有成员、保护成员和公有成员。友元函数不能直接访问对象的数据成员,只能通过传入的对象参数来访问。友元关系是单向的,不具有交换性。友元关系也不具有传递性。
13.常对象一经初始化就不能改了。const可以用于重载函数(普通成员函数与常成员函数)。常对象只能用常成员函数访问。
14.基类的构造函数和析构函数是不能被继承的。当创建派生类对象时,首先执行基类的构造函数,随后再执行派生类的构造函数;当撤销派生类对象时,则先执行派生类的析构函数,随后再执行基类的析构函数。
15.派生类的构造函数和含有其他类对象成员的构造函数很像,但是不同。前者成员初始化列表用的是类名,后者成员初始化列表用的是对象名。执行顺序相同,前者是先基类构造再派生构造,后者是先对象成员类构造再对象构造。成员初始化列表只有在构造函数定义的时候才能写,如果类内只是声明的话,不要写。
16.基类使用默认构造函数时,派生类可以不写15条所述的内容;如果派生类也使用默认构造函数,则都可略去。但是,只要基类的构造函数有一个参数,派生类都要写构造函数和成员初始化列表。
17.当一个派生类内含有基类的对象时,先执行基类的构造函数,再执行派生类内嵌的基类对象的构造函数,再执行派生类的构造函数方法体。
18.访问声明,就是在私有继承的情况下,将基类的保护成员或公有成员在派生类中用“基类::XXX”的形式写在同名段中,利用这种方法,该成员就成为派生类的保护成员或公有成员了。访问声明中只含有不带类型和参数的函数名或变量名。因此,对基类中的重载的所有同名函数都有效。
19.C++支持多重继承,Java不支持多重继承。多重继承时,基类的构造函数的调用顺序跟声明派生类时指定的各个基类的顺序相同,与初始化列表的顺序无关。
20.C++虚基类。 Class 派生类名:virtual 继承方式 基类名{......} 此时基类的成员只保留一份。在虚基类没有默认构造函数的情况下,即虚基类的构造函数有参数的情况下,只要派生类继承的类里面有继承过虚基类的,派生类就需要在初始化成员列表上加上虚基类的初始化。并且,只有派生类里面的初始化成员列表对虚基类的初始化有效,即只在这里执行一次虚基类的构造函数,继承虚基类的其他类的初始化列表对于虚基类的初始化都将被忽略。不是虚基类的话,派生类没必要初始化“爷爷辈”的基类。
21.Java抽象类。Java抽象类只是介于类和接口之间的存在,可以在抽象类里面声明抽象方法。Java中的抽象方法这个概念与C++中的纯虚函数一样,C++中含有纯虚函数的类也叫抽象类。C++纯虚函数没有方法体,取而代之的是声明后面跟着=0,如果有方法体,那叫虚函数,Java中没有虚函数这种东西。C++的虚基类跟虚函数没什么关系,虚基类只是一种继承方式。
22.C++中规定:基类的对象指针可以指向它的公用派生类对象,但是当指向公有派生类对象时,它只能访问派生类中从基类中继承而来的成员,而不能访问公有派生类中定义的成员。
23.虚函数的存在就是为了让基类的对象指针能够使用派生类的方法(基类和派生类里面相应的方法都声明为虚函数,二者的声明必须完全相同)。虚函数必须是成员函数,不能是友元函数,也不能是静态成员函数。虚函数只有使用基类指针才能发挥效果,使用对象名和点运算符也可以调用虚函数,但是是在编译时进行的,没有利用虚函数的特性,只有通过基类指针访问虚函数才能获得运行时的多态性。
24.虚析构函数。当基类指针指向一个new出来的无名派生类对象时,delete 该指针只会执行基类的析构函数。但是,如果将基类的析构函数声明为虚析构函数,就可以正确调用派生类析构函数和基类析构函数了。
25.在派生类中重新定义基类的虚函数是函数重载的另一种形式。与一般的重载不同,虚函数重载需要保证声明完全相同的(必须是一模一样的,包括顺序也必须相同)。
26.赋值兼容关系。凡是使用基类的地方都可以用公有派生类代替,但是只能使用从基类继承来的成员。
(1)派生类对象可以向基类对象赋值。
(2)派生类对象可以初始化基类对象的引用。
(3)派生类对象的地址(私有派生对象不行)可以赋给指向基类对象的指针,这句话反过来不成立,即派生类指针不能指向基类对象。
(4)如果函数的形参是基类对象或基类对象的引用,在调用函数时可以用派生类对象作为实参。
27.运算符重载。
(1)"."、".*"、"::"、"sizeof"、"?:"这5个运算符不能重载。
(2)不允许定义新的运算符。
(3)应该保证语义一致,例如加法不应重载为减法。
(4)重载运算符不改变运算符的个数。
(5)重载运算符不改变运算符的优先级。
(6)重载运算符不改变运算符原有的结合特性。
(7)重载运算符的参数至少有一个类对象或者是类对象的引用,不能全是C++标准类型。
(8)运算符重载函数可以是普通函数、类成员函数、友元函数。
(9)“=” ,即赋值运算符一般不需要重载,友元函数不能重载“=”、“[ ]”、“()”。
28.运算符重载函数可以是友元函数的必要性。假设有一个类名为A,“A=A+1”这个语句无论重载运算符函数是类成员函数还是友元函数都可以正确执行。但是如果是“A=1+A”这种情况,友元函数不会出错,而类成员函数会因为1这个标准数据类型里面没有对应的类成员函数报错。换句话说,重载运算符作为友元函数就是为了不同类型的对象做运算而准备的。
29.++、--运算符重载格式
(1)类成员函数:“X operator++()”或者“X operator++(int)”。前者是++X,后者是X++。
(2)友元函数:“friend operator++(X&)”或者“friend operator++(Y&,int)”。前者是++X,后者是X++。
(3)前缀意味着返回运算后的当前对象;后缀意味着返回运算前的当前对象。
(4)多出来的int参数没有任何卵用,只是用来给编译器区分的。
30.深复制、浅复制。可以在复制构造函数里面解决,也可以通过重载=等运算符解决,推荐在复制构造函数里面解决。
31.转换构造函数。跟复制构造函数很像,既可以通过()运算符调用,也可通过=调用。转换构造函数只能有1个参数。
32.类型转换函数。效果跟转换构造函数相反,将自己转换成其他类型。用的时候跟强制类型转换一样,比如double(XXX类对象)。类型转换函数只能作为类成员函数,没有参数,不能指定函数类型,必须有return。可以有多个类型转换函数。如果不显式使用类型转换函数,并且没有重载+运算符,直接将两个类对象相加,就会隐式调用类型转换函数,进行运算。总之,将两个类对象相加,编译器会通过各种可行的、已定义的类型转换函数,将类型转换为可以相加的类型,然后执行运算符+的函数。
33.模板。C++模板与Java泛型不同的地方是。模板是“雕版印刷术”,即改个字需要全部重新雕刻;泛型是“活字印刷术”,即改个字只需要换个字模具就行了,用的还是原来那套。
34.函数模板可以与同名非模板函数进行重载。当调用同名函数时,先从非模板的函数里面找,找不到再用模板生成。
35.cout<<与cout.put不同的地方是put的参数可以是ASCII码。cin.get与cin>>不同之处是,get可以读入空白字符,cin默认拒绝接收空白字符。cin.getline(字符数组/指针,字符个数n,终止标志字符)。cin可以读入各类数据(重载后还可以读入自定义类型的数据),cin.getline()只能用于输入字符型数据。cin<<以空白字符作为终止状态,cin.getline()可以读取连续的字符,包括空格。cin.ignore(n,终止字符)可以跳过n个字符或者遇到EOF时提前结束。
36.重载的插入运算符和提取运算符均不能作为类成员函数,只能作为普通函数或者友元函数。
37.文件输入输出,STL标准模板库内容比较多比较杂,这里就不写了。