C++琐碎知识整理

C++琐碎知识整理

1.C++与C一样,用终止符(terminator)将两条语句分开,终止符是一个分号,它是语句的结束标记,是语句的组成部分,而不是语句之间的标记,所以C++语句一定不能省略分号。

2.通常,main()被启动代码调用,而启动代码是由编译器添加到程序中的,是程序和操作系统之间的桥梁,该函数头描述的是main()和操作系统之间的接口。

3.在C语言中,省略返回类型相当于说类型是int,但在C++中淘汰了这种用法。main()函数返回类型是void的不是当前标准强制的一个选项,因此在有些系统上不能工作,应该避免这种格式。
C++琐碎知识整理_第1张图片

4.如果编译器到达main()函数结尾时没有遇到返回语句,则认为结尾有return 0; 只适用于main()函数
C++琐碎知识整理_第2张图片
可以看到普通的要求要返回的函数没有return的情况会有警告,但不会报错,而main函数可以没有return

5.C++风格的注释是两个正斜杠// ,而C风格的注释是 \ * * \ ,现在C++标准也在C语言中加了//注释

6.预处理器操作:在源代码被编译之前,替换或添加文本,#include这一行就是把iostream文件的内容替换这一行,因为这是一个预处理指令,并不是一个C++语句,所以不用分号作为结束。

7.C语言中头文件扩展名用.h,C++保留了这种用法。C++风格的头文件没有扩展名,有一些在C的基础上去掉.h,有些加上前缀c,表示来自C语言,比如 math.h -> cmath .

8.在C++中,没有.h的头文件可以包含名称空间,有.h就不行,例如

使用 iostream.h 和 cout 或者 使用iostream 和 std::cout

(我用iostream.h 和 cout 会报错,显示找不到iostream.h )

9.使用using编译指令使得名称空间的所有名称都可用,这是一种偷懒的做法,在大型项目中这是一个潜在的问题。最好是只使需要的名称可用。比如using std::cin;,对于简单程序来说无关紧要。
C++琐碎知识整理_第3张图片

10.cout和cin都是一个预定义对象,可以智能识别并处理信息。

11.插入运算符<<将右侧的信息插入到流中,这是一个运算符重载的例子,<<也可表示位运算的左移运算符,编译器通过上下文来确定运算符的含义。

12.C语言本身也有一些运算符重载的情况,比如&表示取地址运算符,也可以表示按位与,*表示乘法,也表示间址访问。但是C语言不能用户自定义函数重载。

13.在C++中输出时另起一行用endl控制符,比如cout<

14.一行代码中不可分割的元素叫做标记(token),通常必须用空格,制表符或回车将两个标记分开。空格,制表符和回车统称为空白(white space).

15.声明语句:

int a;

这条语句提供了两项信息:1.需要的内存 2.该内存单元的名称。指出该程序需要足够的大小空间来存储一个整数,大小取决于实现。指出程序将使用a来标识存储在该内存单元中的值。

16.在C++中所有变量都必须声明,否则当使用时编译器将报错。

17.定义:程序中的声明语句叫做定义声明(defining declaration)语句,简称定义。声明不一定是定义。

18.在C中变量的声明都必须放在函数刚开始的位置,但C++中只要保证在声明后使用,且在同一个作用域里就行了。

19.C++和C有一项不寻常的特性–可以连续使用赋值运算符。

a=b=1;

从右向左进行,1被赋给b,b再赋给a

20.C++程序必须为程序中每个函数提供原型。函数原型只描述函数接口,描述的是发送给函数的信息和返回的信息。函数定义中包含了函数的编译代码。库文件包含了函数的编译代码,头文件包含了函数原型。

21.在创建变量时对它赋值,这个过程叫做初始化(initialization).

int a=1;

22.在有些语言中,又返回值的函数称为函数(function),没有返回值的函数称为过程(procedure)或子程序(subroutine)。但在C和C++中都称为函数。

23.C++不允许将函数定义嵌套在另一个函数定义里,每个函数定义都是独立的,所有函数的创建都是平等的。

23.可以认为,main()函数被操作系统调用,返回值通常也被叫做退出值,为0意味着程序运行成功,非0则意味着出现问题。

24.main不是关键字,但它是一个必不可少的函数名称,可以把main用作变量名,但有些时候会出错,因此最好不要这样做。

25.让程序能够访问名称空间std的方法有很多种,下面是常见的四种。

①将using namespace std;放到函数定义前面。

②将using namespace std;放到函数定义里,这样函数里就可以用std的函数了。

③用using std::cout这样的编译指令。

④完全不使用using,而在需要使用std中的元素的时候使用前缀std::

C++琐碎知识整理_第4张图片
由图可知,这里的using作用域在main函数里

1.C++对于名称的长度没有限制,但有些平台有长度限制。与C(C99标准)不同的是,后者只保留名称中的前63个字符有意义。

2.C++确保了数据类型的最小长度,short至少是16位,int至少与short一样,long至少32位且至少与int一样,long long至少64位,且至少与long一样。

3.在美国基本字符集通常是ASCII和EBCDIC字符集,在使用这两种字符集的系统中,C++字节通常包含8位,而有些系统用更大的字符集,比如Unicode,因此有些实现有可能用16位或32位的字节。

4.对类型名用sizeof运算符时应将名称放在括号中,但对变量名使用sizeof时括号是可选的。

5.C++有一种C语言没有的初始化语法:

int a(123);

6.如果不对函数内部定义的变量初始化,该变量的值是不确定是,这意味着该变量的值是它被创建之前,相应内存单元保存的值。所以在声明变量时对它初始化,可避免以后忘记给他赋值的情况发生。

7.C++11中可以用统一的初始化方式:

int a={123};

等号也可以不用

int b{456};

大括号里也可以不包含任何东西,这时变量将被初始化为0

int c={};

int d{};

这有助于防范类型转换错误,是一种通用的初始化语法。

8.整形字面值是显示地书写的常量,C++用前一两位标识数字常量的基数。如果第一位位1-9则基数位10,如果第一位是0,第二位是1-7则基数为8,如果前两位为0x或0X则基数是16。默认情况下cout以十进制格式现实整数。

C++琐碎知识整理_第5张图片
C++琐碎知识整理_第6张图片

由图可知,实际上只要第一位是0,第二位是0-7,就会被当成是8进制。

9.char类型是另一种整型,虽然它最长用来处理字符,但也可以将它用做比short更小的整型。

10.当输入字符M时,cin将键盘输入的M转换成77,输出时,cout将值77转换成所显示的字符M,也就是说内存里存的其实是77这个数字,当输出时cout会自动识别到char类型,并输出77对应的字符。

11.通用字符名。用法类似转义字符,以\u或\U打头,\u后面是4个十六进制位,\U后面是8个十六进制位。表示字符的ISO 10646码点。

12.char也可以有符号和无符号,signed char范围从-128-127,unsigned char 范围从0-255

13.cin和cout将输入和输出看作是、char流,因此不适于用来处理wchar_t类型。iostream头文件的最新版本提供了作用相似的工具–wcin和wcout,用于处理wchar_t。可加上前缀L来指示宽字符常量和宽字符串

14.随着编程人员日益熟悉Unicode,类型wchar_t不能再满足需求,它的长度和符号随实现而异,因此C++11新增了类型char16_t和char32_t,都是无符号的,前者16位,后者32位,前缀u表示char16_t字符常量,前缀U表示char32_t字符常量.

15.const限定符。应该在声明中队const初始化,否则该常量的值是不确定的,且无法修改。

C++琐碎知识整理_第7张图片

由图可知,不允许声明const时不初始化,不能对常量修改。

16.const比#define好:

​ ①const可以明确指定类型

​ ②const可以利用作用域将定义限制在特定的函数或文件中。编译器处理宏的时机是预处理阶段,编译器按文本顺序处理,遇到宏时就定义一个宏变量。#define是否生效取决于文本的顺序。
C++琐碎知识整理_第8张图片
如图,#define放在了main之前的一个函数里,虽然没有调用func,但还是起作用了,而把#define放到main之后就不行了。
17.在C++除法中,如果有存在一个数是浮点数,则小数部分保留,否则小数部分被丢弃,结果是整数。

18.由此,除法可分为int除法,float除法,double除法等等,这是运算符重载的又一个例子。

19.自动类型转换:

①将一种算术类型的值赋给另一种算数类型的变量时,C++对值转换。

②表达式中包含不同类型时,C++对值转换。

③将参数传递给函数时,C++对值转换。

20.在计算表达式时,C++将bool,char,signed char和short值转化为int,比如bool类型false转化为0,true转化为1,这些转换被称为整形提升(integral promotion),例如:

short a=1;

short b=2;

short c=a+b;

虽然a和b都是short,但在计算a+b时先把a和b都转换成int类型,再相加,最后结果转换成short类型。

通常将int类型选择为计算机最自然的类型,意味着计算机使用这种类型时,运算速度可能最快。

21.传递参数时的类型转换通常由C++函数原型控制,也可以取消原型对参数传递的控制。

22.强制类型转换不会修改变量本身,而是创建一个新的,指定类型的值。

(int)a;
int(a);

第一种格式来自C语言,第二种格式是存粹的C++,新格式的思想是要让强制类型转换就像是函数调用。

23.C++还引入了四种强制类型转换运算符

1.声明数组时的长度size不能是变量,变量的值在程序运行时设置。

2.数组必须是特定类型的数组,比如:

int a[10];

a的类型不是数组,而是 int数组

3.编译器不会检查下标是否有效,越界不会指出错误

4.sizeof用于数组名时返回的是整个数组的字节数

5.只有在定义数组时才能初始化,不能将一个数组赋给另一个数组。

6.如果只对数组的一部分进行初始化,则编译器将把其他元素设置为0

7.字符串常量和字符常量不一样,比如’s’表示一个字符,表示一个ascii的数字,"s"表示的是两个字符,即s和\0,且"s"表示的是字符串所在的地址。

8.拼接字符串常量:任何两个由空白分隔的字符串常量都将自动拼接成一个。
C++琐碎知识整理_第9张图片

9.cin使用空白(空格,制表符,换行符)确定字符串结束的位置

10.读取一行字符串输入:getline和get

cin.getline()通过换行符来确定输入结尾,第一个参数是要输入的数组的名称,第二个参数是要读取的字符数,会读取结尾的换行符

get()则不读取最后的换行符,而是丢弃换行符,将其留在输入队列中。幸运的是,get有一种变体,不带任何参数的cin.get()调用可读取下一个字符,因此可以用它来处理换行符。

C++琐碎知识整理_第10张图片

由图可知,我只输入了一行,第二行没有让我输入,这是因为我输入一行之后输入队列里留下了一个换行符,第二次读的时候直接遇到了换行符,于是认为读到末尾了就结束了。

C++琐碎知识整理_第11张图片

这次用cin.get()把换行符吃掉了,就没有这个问题了。

而cin.getline()则没有这个问题,因为它读一行的时候换行符也读进去了。

11.要使用string类,必须包含string头文件,string类位于std名称空间中。

12.string是C++风格的字符串类型(C没有字符串类型,只是字符数组罢了),它的赋值,插入等操作比字符数组要方便的多。字符数组总是存在目标数组过小的问题,而string会自动调节大小

13.未初始化的string长度是0,不同于其他基本类型,因为string是一个类,自动调用构造函数初始化。

14.C++11新增的一种类型是原始(raw)字符串。在原始字符串中,字符表示的就是自己,将"(和)"用作定界符,并使用前缀R来表示原始字符串,当字符串里包含)的时候会出错,可以在表示字符串开头的"和(之间加入其他字符,即自定义定界符,结尾的*和)之间也必须包含这些字符。

C++琐碎知识整理_第12张图片

如图,这个例子用"abc(和)abc"作为定界符,且字符串里的转义字符不会转义。

15.结构中的位字段。C++允许指定占用特定的结构成员,使得创建与某个硬件设备上的寄存器对应的数据结构非常方便。每个成员都被称为位字段。通常用在低级编程中。

C++琐碎知识整理_第13张图片

由图可知,我给a分配了3个bits,所以它能够表示-4~3的数字

16.共用体,一种数据格式,能够存储不同的数据类型,但只能同时存储其中的一种类型,但必须由足够的空间存储最大的成员。可节省空间,对某些内存非常宝贵的应用程序来说很有用。

17.枚举类型:一种创建符号常量的方式,这种方式可以替代const,还允许定义新类型。如果只打算使用常量,而不创建枚举类型的变量,则可以省略枚举类型的名称。

18.设置枚举量的值。指定的值必须是整数,后面没有被初始化的枚举量比前面的枚举量大1.

19.枚举的取值范围。找到大于最大值的,最小的2的幂,再-1,就是上限。下限同理。
20.面向对象编程与传统的过程性编程的区别在于,OOP强调的是在运行阶段进行决策。

21.运算符*称为间接值或解除引用运算符。

22.声明和初始化指针。

​ C程序员用这种格式:int *ptr; 这强调 *ptr是一个int类型的值。

​ C++程序员用这种格式:int* ptr; 这强调int*是一种类型,指向int的指针。

在C++中,int*是一种复合类型,是指向int的指针。

23.一定要在对指针应用接触引用运算符之前,将指针初始化位一个确定的适当的地址。

24.不能简单的将整数赋给指针,应通过强制类型转换将数字转换为适当的地址类型。

25.一定要配对地使用new和delete,否则将发生内存泄漏,也就是说,被分配的内存再也无法使用了。

26.不要尝试释放已经释放的内存块,结果将是不确定的,然而,对空指针用delete是安全的

27.一般来说说,不要创建两个指向同一个内存块的指针,以防错误地对一块内存释放两次。

28.使用new和delete时应遵循一下规则:

①不要使用delete释放不是new分配的内存

②不要使用delete释放同一个内存块两次

③如果使用new[]为数组分配内存,应使用delete[]来释放

④如果使用new为一个实体分配内存,则应使用delete(没有方括号)来释放

⑤对空指针应用delete是安全的。

29.数组名是产量,不能修改数组名,但指针是变量,可以修改它的值。

30.C++不允许把字符常量赋给一个普通的指针,因为常量不允许被修改,但可以赋给以一个常指针。

C++琐碎知识整理_第14张图片

31.C++把字符常量赋给字符数组时,实际上复制了整个字符串,而不是复制地址。
C++琐碎知识整理_第15张图片
32.

int tell[10];

cout<

cout<<&tell<

从数字上说,这两个地址相同,但从概念上说,&tell[0]是一个4字节内存块的地址,即tell,而&tell是一个40字节内存块的地址,在+1的时候会有所不同。

33.所有方括号数组表示法等同于对指针解除引用。

34.如果给cout一个字符的地址,则它将从该字符开始打印,直到遇到空字符为止。

35.编译器可能存储一个字符串字面值多个副本,也可能只存储一个副本

36.一般来说,如果给cout提供一个指针,它将打印地址,但如果指针的类型为char*,则cout将显示指向的字符串,如果要显示的是字符串的地址,则必须强制转换为另一种指针类型,如int *

1.C++将赋值表达式的值定义为左侧成员的值

2.C++表达式是值或值与运算符的组合,每个C++表达式都有值

3.当判定表达式的值这种操作改变了内存中数据的值时,我们说表达式有副作用(side effect).

4.从表达式到语句的转换很容易,只要加分号即可。

5.在C++中可以在for循环的初始化部分中声明变量,但不适用于原来的句法。这是因为C++把for循环修改成

for(初始化语句 表达式;表达式)

初始化语句因为是一个语句,所以结尾自带分号,而如果不是声明,在结尾加了分号也变成了语句,这就是C++可以在for里声明的原因。

6.顺序点(sequence point)是程序执行过程中的一个点,在这里,进入下一步之前将确保对所有的副作用都进行评估。

7.来看看下面的语句

y=( 4 + x++) + ( 6 + x++ );

表达式 4 + x++ 不是一个完整表达式,因此C++不保证x的值在计算子表达式4 + x++后立刻+1,而整条赋值语句是一个完整表达式,分号标示了顺序点,因此C++只保证程序执行到下一条语句之前,x递增两次,但没有规定是计算每个子表达式之后将x递增还是在整个表达式计算完毕之后才将x递增。

8.自增自减运算符的前缀格式和后缀格式的执行速度有细微差别,前缀将值+!再返回结果,后缀先赋值一个副本,再+1,然后将副本返回。因此对于类,前缀格式的效率比后缀高。

9.逗号运算符。可以用逗号把两个表达式合并成一个。优先级最低,先计算第一个表达式,再计算第二个表达式,换句话说,逗号是一个顺序点。

10.文件尾条件,在windows命令提示符模式下,可以在任意位置按Ctrl+Z和Enter,通过键盘模拟文件尾条件。

11.方法cin.get(char)函数返回的是一个cin对象,istream类提供了一个可以将istream对象转换成bool值的函数。

12.通常,EOF被定义为值-1,因为没有ASCII码为-1的字符。

1.将variable== value反转为value== variable,可以以此来捕获将相等运算符误写为赋值运算符的错误

2.不要使用数学符号将其表示为:

if( 17 < age < 35)

编译器不会捕获这种错误,因为它仍然是有效的C++语法,它的含义是

if( (17 < age) < 35)

3.C++确保从左到右进行计算逻辑表达式,并在知道答案之后立刻停止。

4.并不是所有键盘都提供了用作逻辑运算符的符号,因此C++标准提供了另一种表示方法,标识符 and , or 和 not 都是C++保留字,这意味着不能将它们用作变量名等。它们不是关键字,因为它们都是已有语言特性的另一种表示方式。另外,它们并不是C语言中的保留字,但包含头文件iso646.h之后就可以用作运算符。而C++不要求使用头文件。

5.在switch语句中,括号里的表达式必须是一个结果为整数值的表达式,每个标签都必须是整数常量表达式。

6.C++中的case标签只是行标签,而不是选项之间的界线,也就是说程序跳到case中特定代码之后,将依次执行之后的所有语句,除非遇到break。

7.Windows文本文件的每行都以回车字符和换行符结尾,通常,C++再读取文件时将这两个字符转换为换行符。

1.库函数是已经定义和编译好了的函数,同时可以使用标准头文件提供原型。

2.C++对于返回值的类型,不能是数组,但可以将数组作为结构或对象组成部分返回。

3.原型描述了函数到编译器的接口,它将函数返回值的类型以及参数的类型和数量告诉编译器

4.避免使用函数原型的唯一方法是,在首次使用函数之前定义函数

5.C++的编程风格是将main放在最前面,因为它通常提供了程序的整体结构

6.在函数原型的参数列表中,可以包含变量名,也可以不包含,它相当于占位符,因此不必与与函数定义中的变量名相同。

7.C++中,不指定参数列表时应使用省略号,通常仅当与接受可变参数的C函数交互时才需要这样做

8.在编译阶段进行的原型化被称为静态类型检查

9.用于接收传递值的变量被称为形参。传递给函数的值被称为实参。C++标准使用参数(argument)表示实参,使用参量(parameter)表示形参

10.在C++中,当且仅当用于函数头或函数原型中,int *arr和int arr[]的含义才相同,都意味着arr是一个int指针,在其他上下文中含义并不相同。

11.除了常规的提供数组首地址和数组长度的给函数传递数组的方式,还有另一种给函数提供所需信息的方法,即指定元素区间,这可以通过传递两个指针来完成,一个指向开头,一个指向尾部,例如C++标准模板库,STL使用“超尾”概念指定区间,也就是说对于数组,标示结尾的参数是最后一个元素后面的指针。

12.尽可能使用const

13.与C语言不同的是,C++不允许main调用自己

1.内联函数是C++为提高运行速度所作的一项改进。对于内联代码,程序无需跳到另一个位置处执行代码再跳回来,因此运行速度比常规函数块,但代价是需要占用更多内存。

2.程序员请求将函数作为内联函数时,编译器不一定会满足这种要求,它可能认为该函数过大或注意到函数调用了自己。而有些编译器没有启用和实现这种特性。

3.引用和指针的区别:

引用必须在声明时将其初始化,而不能像指针那样,先声明再赋值。

4.如果引用参数是const,则编译器将在下面两种情况下生成临时变量:

实参的类型正确,但不是左值

实参的类型不正确,但可以转换成正确的类型

5.左值是可被引用的数据对象。在C语言中,左值最初指的是可出现在赋值语句左边的实体,但这是引入const之前的情况。

6.如果接受引用参数的函数的意图是修改作为参数传递的变量,则创建临时变量将阻止这种意图的实现。解决方法是禁止创建临时变量。

7.返回引用时最重要的一点,避免返回函数终止时不再存在的内存单元的引用

8.类设计的语义常常要求使用引用,传递类对象参数的标准方法是按引用传递

9.函数默认参数必须从右向左添加默认值,不能跳过任何参数。且要么在原型指定默认值,定义时不指定,要么没有原型,只在定义时指定。

10.函数重载的关键是函数的参数列表,也称为函数特征标(function signature),如果两个函数的参数数目和类型相同,同时参数的排列顺序相同,则特征标相同,而变量名是无关紧要的。(函数特征标也叫函数签名,看英文就知道了)

11.名称修饰(名称矫正):它根据函数原型中指定的形参类型对每个函数名进行加密。

1.指定基本类型完成了三项工作

①确定数据对象需要的内存数量

②决定如何解释内存中的位

③决定可使用数据对象执行的操作或方法

2.公有成员函数是程度和对象的私有成员之间的桥梁,提供了程序和对象之间的接口。防止程序直接访问数据称为数据隐藏

3.数据隐藏的原则是将实现细节从接口设计中分离。如果以后找到了更好的实现方法,可以对这些细节修改,而不需修改程序接口,维护起来更容易。

4.C++对结构进行了扩展,使之具有与类相同的特性。它们唯一的区别是,结构的默认访问类型是public,类为private

(当然还有更细的区别)

5.类方法的完整名称包括类名。Stock::update()是函数的限定名(qualified name);而update()是缩写(非限定名),它只能用在类作用域中使用。

6.定义在类声明中的函数都将自动成为内联函数。也可以在类声明之外定义成员函数,使之成为内联函数

7.根据改写规则(rewrite rule),在类声明中定义方法等于用原型替换方法定义,然后在类声明的后面将定义改为内联函数

8.所创建的每个对象都有自己的存储空间,用于存储其内部变量和类成员,但同一个类的所有对象共享一组类方法,即每种方法只有一个副本。

9.如果程序员没有提供析构函数,编译器将隐式地声明一个默认析构函数,并在发现导致对象被删除的代码后,提供默认析构函数的定义。

10.初始化对象时,可以显式和隐式地调用构造函数进行初始化,比如

A a(1,2,3);

A a=A(1,2,3);

这两种效果等价,第二种在不同编译器里可能不同,第二种显示调用用构造函数创建一个临时对象,然后将临时对象复制到a中,并丢弃它。因此这里可能会执行两次析构函数。

11.构造函数不仅可以用于初始化新对象,例如

a=A(1,2,3);

通过让构造函数创建一个新的临时对象,然后将其内容复制给a实现,然后调用析构函数以删除临时对象。

12.接受一个参数的构造函数允许使用赋值语法将对象初始化为一个值。这种特性可能导致问题

13.每个成员函数都有一个this指针,包括构造函数和析构函数。

14.初始化对象数组的方法:首先使用默认构造函数创建数组元素,然后花括号中的构造函数将创建临时对象,然后将临时对象的内容复制到相应元素中。因此要创建对象数组,这个类必须有默认构造函数。(我试了一下似乎并没有先使用默认构造函数创建数组元素,只要保证花括号里的构造函数都存在即可)

15.在类中定义的名称的作用域都为整个类

16.在类中创建常量不能像这样

const int a=12;

因为声明类只是描述了对象的形式,并没有创建对象,因此,在创建对象之前,将没有用于存储值的空间(C++11提供了成员初始化)

第一种方法是在类中声明一个枚举。

enum {months=12};

没有提供枚举名,只是创建了一个符号常量

第二种方法是用static

static const int months=12;

该常量与其他静态变量存储在一起,而不是存储在对象里

17.传统的枚举类型直接使用相应的符号常量,如果有两个枚举有相同的符号,则会发生冲突,因此C++11新增了作用域内枚举。

enum class A{a,b,c,d};

enum class B{c,d,e,f};

A::c和B::c可以区分

还提高了类型安全。作用域内枚举不能隐式地转换为整型,默认情况下C++11作用域内枚举的底层类型为int,另外还提供了一种语法

enum class : short A {a,b,c,d};

:short将底层类型指定为short

十一

1.当返回一个类的对象时,意味着程序在删除局部的对象之前构造它的拷贝,调用函数将得到该拷贝。

2.不要返回局部变量或临时对象的应用。

3.重载限制:

重载后的运算符必须至少有一个操作数是用户定义的类型,这将防止用户为标准类型重载运算符。

使用运算符时不能违反运算符原来的句法规则

不能修改优先级

不能创建新的运算符

不能重载一下运算符:

.:成员运算符

.*:成员指针运算符

:::作用域解析运算符

?::条件运算符

typeid:一个RTTI原算法

和四种强制类型转换运算符

下面的运算符只能通过成员函数重载:

=:赋值运算符

():函数调用运算符

[]:下标运算符

->:通过指针访问类成员的运算符

4.友元函数的原型放在类声明中,原型前加friend

虽然友元函数是在类声明中声明的,但它不是成员函数(也可以没有声明,那就不是友元只是一个普通的函数)

虽然不是成员函数但是它与成员函数的访问权限相同(参数种有自己的类的话就可以访问它的私有)

5.友元函数的目的之一就是解决运算符重载函数作为成员函数时,参数的顺序不能调换的问题。

6.重载<<必须使用友元,如果不用的话,就会像这样

trip<

看起来很怪。

7.在定义运算符时,必须选择其中一种格式,而不能同时选择两种格式,否则被视为二义性错误。

Stone myCat;

myCat=19.6;

程序将使用构造函数Stone(double)来创建一个临时Stone对象,将19.6作为初始值,随后逐成员赋值方式将该临时对象的内容复制到myCat,这一过程称为隐式转换。

9.只有接受一个参数的构造函数才能作为转换函数。如果第二个参数提供默认值,也可以用于转换。

10.这种转换可能会导致意料之外的问题,因此C++新增了关键字explicit用于关闭这种自动特性。

11.构造函数用于将某种类型转换成类类型,要进行相反的操作必须使用特殊的C++运算符函数–转换函数。

12.转换函数:operator typeName();

必须是类方法

不能指定返回类型

不能有参数

比如 operator int();

13.int指出了要转换成的类型,因此不用指定返回类型,是类方法意味着它通过类对象调用,从而告知函数要转换的值,因此不需要参数。

14.实际中不这样用,为了避免一些意外的错误,往往用一个功能相同的非转换函数替换,仅被显式地调用。

比如

int plb=poppings.Stone_to_Int();

像java和c#等都是这样用的。

你可能感兴趣的:(C++相关,c++,开发语言)