1.C++标识符规则:
(1)第一个字符必须是字母(不分大小写)或下划线(_);
(2)后跟字母(不分大小写)、下划线(_)或数字组成;
(3)标识符中的大小写字母有区别;
(4)不能与c编译系统已经预定义的、具有特殊用途的保留标识符(即关键字)同名。比如,不能将标识符命名为float,auto,break,case,this,try,for,while,int,char,short, unsigned,等等。
2.不同数据类型进行运算时,运算结果会转换成为精度较高的数据类型。
3.重载函数:
(1)函数名称必须相同。
(2)参数列表必须不同(个数不同、类型不同、参数排列顺序不同等)。
(3)函数的返回类型可以相同也可以不相同。
(4)仅仅返回类型不同不足以成为函数的重载。
4.C++数组声明时,只有行数可以省略,列数不可以省略。
5.拷贝构造函数:是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。拷贝构造函数通常用于:
(1)通过使用另一个同类型的对象来初始化新创建的对象。
(2)复制对象把它作为参数传递给函数。
(3)复制对象,并从函数返回这个对象。
如果在类中没有定义拷贝构造函数,编译器会自行定义一个。如果类带有指针变量,并有动态内存分配,则它必须有一个拷贝构造函数。
浅拷贝与深拷贝
拷贝构造函数和赋值运算符重载函数都会涉及到这个问题。
所谓浅拷贝,就是说编译器提供的默认的拷贝构造函数和赋值运算符重载函数,仅仅是将对象a中各个数据成员的值拷贝给对象b中对应的数据成员(这里假设a、b为同一个类的两个对象,且用a拷贝出b或用a来给b赋值),而不做其它任何事。
假设我们将例1中显式提供的拷贝构造函数注释掉,然后同样执行MyStr str3 =
str2;语句,此时调用默认的拷贝构造函数,它只是将str2的id值和nane值拷贝到str3,这样,str2和str3中的name值是相同的,即它们指向内存中的同一区域(在例1中,是字符串”hhxx”)。如下图
这样,会有两个致命的错误
①当我们通过str2修改它的name时,str3的name也会被修改!
②当执行str2和str3的析构函数时,会导致同一内存区域释放两次,程序崩溃!
这是万万不可行的,所以我们必须通过显式提供拷贝构造函数以避免这样的问题。就像我们在例1中做的那样,先判断被拷贝者的name是否为空,若否,dalete
name(后面会解释为什么要这么做),然后,为name重新申请空间,再将拷贝者name中的数据拷贝到被拷贝者的name中。执行后,如图
这样,str2.name和str3.name各自独立,避免了上面两个致命错误。
我们是以拷贝构造函数为例说明的,赋值运算符重载函数也是同样的道理
6.构造函数:
(1)构造函数没有返回值
(2)构造函数名必须与类名一致
(3)一个类中可以有多个构造函数,若没有写构造函数,系统会生成一个空参的构造函数。
7.常对象
(1)常对象必须在定义时就声明为常对象。
(2)如果一个对象被声明为常对象,则不能调用该对象的非const型的成员函数(除了由系统自动调用的隐式构造函数和析构函数),目的是为了防止非const型函数修改数据成员的值。
8.友元函数:C++中引入友元函数,是为在该类中提供一个对外(除了他自己意外)访问的窗口;这个友元函数他不属于该类的成员函数,他是定义在类外的普通函数,只是在类中声明该函数可以直接访问类中的private或者protected成员。
(1)类中通过使用关键字friend 来修饰友元函数,但该函数并不是类的成员函数,其声明可以放在类的私有部分,也可放在共有部分。友元函数的定义在类体外实现,不需要加类限定。
(2)一个类中的成员函数可以是另外一个类的友元函数,而且一个函数可以是多个类友元函数。
(3)友元函数可以访问类中的私有成员和其他数据,但是访问不可直接使用数据成员,需要通过对对象进行引用。
(4)友元函数在调用上同一般函数一样,不必通过对对象进行引用。
9.友元类:友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一类的友元类。
(1) 友元关系不能被继承。
(2) 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
(3) 友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明。
10.静态成员(static)属于类而不属于对象,它被同一个类的所有对象共享。
11.构造函数参数初始化列表:
(1)常数据成员只能通过构造函数初始化表对其进行初始化,任何其它函数都不能对常数据成员赋值。
12.const与static
(1)const定义的常量在超出其作用域之后其空间会被释放,而static定义的静态常量在函数执行后不会释放其存储空间。
(2)static表示的是静态的,类的静态成员函数、静态成员变量是和类相关的,而不是和类的具体对象相关的。即使没有具体对象,也能调用类的静态成员函数和成员变量。一般类的静态函数几乎就是一个全局函数,只不过它的作用域限于包含它的文件中。
(3)在C++中,static静态成员变量不能在类的内部初始化。在类的内部只是声明,定义必须在类定义体的外部,通常在类的实现文件中初始化,如:double Account::Rate=2.25;static关键字只能用于类定义体内部的声明中,定义时不能标示为static。在C++中,const成员变量也不能在类定义处初始化,只能通过构造函数初始化列表进行,并且必须有构造函数。
(4)const数据成员 只在某个对象生存期内是常量,而对于整个类而言却是可变的。因为类可以创建多个对象,不同的对象其const数据成员的值可以不同。所以不能在类的声明中初始化const数据成员,因为类的对象没被创建时,编译器不知道const数据成员的值是什么。
13.虚函数
(1)构造函数不可以是虚函数,析构函数可以是虚函数。
(2)虚函数不可以是静态函数。
(3)实现动态联编需要使用基类指针调用虚函数。
14.纯虚函数
纯虚函数声明:
virtual 函数类型 函数名 (参数表列) = 0;
(1)纯虚函数没有函数体;
(2)最后面的“=0”并不表示函数返回值为0,它只起形式上的作用,告诉编译系统“这是虚函数”;
(3)这是一个声明语句,最后有分号。
(4)纯虚函数只有函数的名字而不具备函数的功能,不能被调用。
(5)纯虚函数的作用是在基类中为其派生类保留一个函数的名字,以便派生类根据需要对他进行定义。如果在基类中没有保留函数名字,则无法实现多态性。
(6)如果在一个类中声明了纯虚函数,在其派生类中没有对其函数进行定义,则该虚函数在派生类中仍然为纯虚函数。
15.抽象类
①抽象类是指至少有一个纯虚函数的类。它往往表示一些抽象的概念,它的成员函数没有什么意义。
②抽象类是一种特殊的类,它是为了抽象和设计的目的而建立的,它处于继承层次结构的上层。抽象类的主要作用是将有关的类组织在一个继承层次结构中,由它来为它们提供一个公共的根,相关的子类是从这个根派生出来的。
③对于抽象类的使用有几点规定:抽象类只能用作其他类的基类,不能建立抽象类对象;抽象类不能用作参数类型、函数返回类型或显式转换的类型;可以说明指向抽象类的指针和引用,此指针可以指向它的派生类,进而实现多态性。
由此可知,抽象类区别于其他类的最根本的特征是不能定义对象。因此也一般将抽象类的构造函数说明为保护的访问控制。
16.重载函数与重载运算符
重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不相同。
重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。
(1)不可重载的运算符
.成员访问运算符
.*,->*成员指针访问运算符
::域运算符
sizeof:长度运算符
?:条件运算符
# 预处理符号
(2)运算符重载注意事项:
①、运算重载符不可以改变语法结构。
②、运算重载符不可以改变操作数的个数。
③、运算重载符不可以改变优先级。
④、运算重载符不可以改变结合性。
⑤、重载运算符()、[]、->、或者赋值运算符=时,只能将它们重载为成员函数,不能重载为全局函数。
17.类模板&模板类,函数模板&模板函数。
类模板定义格式:
template <类型参数表>
class 类模板名{
成员函数和成员变量
};
编译器由类模板生成类的过程叫类模板的实例化,由类模板实例化得到的类叫模板类。