C/C++基础知识拾遗
C/C++中一些之前的学习中没有涉及到和容易模糊的知识点。
其他专题标签链接:C++拾遗
构造函数中需要初始化列表初始化的成员
在构造函数中需要初始化列表初始化的有如下三种情况
- 带有const修饰的类成员 ,如const int a
- 引用成员数据,如 int &p; (可以参见这里C/C++拾遗之类成员含引用变量)
- 带有引用的类变量 (例如类A中含有有引用成员,类B中定义的类型为A的变量)
static 修饰的变量在类外初始化,const修饰的在参数列表初始化
C/C++中一些之前的学习中没有涉及到和容易模糊的知识点。
其他专题标签链接:C++拾遗
在构造函数中需要初始化列表初始化的有如下三种情况
static 修饰的变量在类外初始化,const修饰的在参数列表初始化
C++11中提供了两种可以实现可变参数的函数实现方式:initializer_list的标准模板类型和可变参数模板。C语言中可以通过省略符类型实现可变数量的参数函数(推荐只有在需要与C函数交互时才使用些方式)。
C++11中的头文件initializer_list中提供了一种标准库类型initializer_list类型,通过该模板可以实现全部实参类型都相同的可变参数函数。使用时只需要将initializer_list类型的参数作为函数形参即可,因为initializer_list可以接受多个元素作为初始化列表,相当于一个变长数组,然后在函数中通过initializer_list头文件中提供的相应函数获取其中的元素即可。initializer_list提供的操作有:
extern “C”的主要作用是让C++中的函数名字使用C语言的编译处理方式(也就是在编译阶段,确切来说 是汇编阶段不对函数名进行mangle处理),这样就可以让C语言代码能够通过“与C语言兼容的方式声明的头文件”来链接C++编译器生成的二进制格式文件中函数。由于C++支持函数重载,而C语言不支持,C++编译器为了支持函数重载,就需要为同名但参数列表不同的函数名指定一个全局唯一的名字(该名字被称为mangled name),也就是编译阶段的mangle name过程,这些名字通常会包含相应的参数列表类型等,不同的编译器实现不同。
由于有extern的修饰,表示被修饰的变量或函数的对外部文件可见,或其定义来自其他文件中,与static的作用刚好相反。
SOF上的回答:http://stackoverflow.com/questions/1041866/in-c-source-what-is-the-effect-of-extern-c
条件编译是由一批预处理器指令,通过指定一些限定的条件,有选择性地对源代码进行预处理,从而实现条件编译。后续的编译、链接等过程都是在预处理之后的代码上进行的,所以预处理之后的代码通常要精简很多(这里精简的思想是包含那个引入的头文件的),无意义的编译指令,根据条件编译代码不需要编译的代码,还有注释都会有预处理之后忽略掉。常用的预的处理器指令主要有(方括号中为后面需要跟的内容):
深拷贝(Deep copy)和浅拷贝(Shallow copy)是指对于类或结构体这类复合类型的变量,当它们的成员变量中含有指针时,在赋值或初始化的过程中,如果只是修改指针的指向,则属于浅拷贝(也称位拷贝)。因为此时指针所指向的实际内容依然只有一份,当其中一个变量销毁时,则该内存将被释放,那么此时另一个变量中将存在悬挂指针。而如果在发生拷贝时首先将需要被拷贝的内容复制到一个新的内存地址,然后再将相应的指针指向该新地址,则称为深拷贝。SOF上的一个相关回答http://stackoverflow.com/questions/184710/what-is-the-difference-between-a-deep-copy-and-a-shallow-copy<>
首先提示:在C++中,对于类型class1来说,class1 a(b);等价于class1 a = b;都将调用拷贝构造函数进行初始化,而不是将后面的语句中使用赋值运算符对a进行赋值。如果要使用赋值运算符将b赋值给a,需要class1 a; a = b;
下面举例说明:
位字段(bit field)也称位域,是一个由signed int 或 unsigned int中一组相邻的位 (C99 还允许 _Bool类型的位字段). 位字段由一个结构体声明建立, 该结构声明为每个字段提供标签, 并决定字段的宽度。使用位字段可以将有些仅需要很少的变量范围的值压缩到一个较小的结构体中。
声明时需要在变量名后面跟冒号(:),冒号后面跟上需要设置的它的位宽度。
或者在在类型名后面跟冒号再跟位宽度,用于对齐占位
有两篇很不错的文章,总结的已经非常好,所以就不再重复详细说明。
其他多数类似文章中没有提及的几个重要的内容(当然上面的文章有详细讲解):
由于历史上考虑到不同机器架构在处理不同位宽的整型时性能不同,所以当时的标准要求保证只要不小于某一宽度即可,具体多宽可由编译器自行决定,导致了在使用int或long时在不同机器上可能存在表现不同的情况。这样也大大降低了程序的稳定性和可移植性。C99标准中定义一组固定位宽的整型,在头文件stdint.h中,建议在编程中无特殊原因都使用这些固定位宽的整型,以保证程序在不同的机器构架下整型变量的大小依然相同。对应于C++11中相应的固定位宽的头文件是cstdin。所涉及到的类型主要有:
SOF上一个比较全面的回答:http://stackoverflow.com/questions/240212/what-is-the-difference-between-new-delete-and-malloc-free
根据理解举例总结如下:
共同点就是都可以用于分配和销毁动态内存。
不同点:
默认是指new/delete :