C++语法规则积累
C++ 中的布尔类型:布尔类型只占用一个bit ,但是如果连续定义多个布尔类型时,编译器可能会多个布尔类型定义在一起。true 编译器用1来表示。false 编译器用0来表示。
将一个其他类型的数据赋给布尔类型变量:C++编译器会将所有的非0的值转换为true(1),将0 转化为false(0)。
三木运算符 ? : :将一个三目运算符作为左值: (a>b?a:b) = 3 C语言不支持(三目运算符返回一个值),但在C++中支持(三目元算符返回变量)。 但是如果可能的返回值有一个是常量值,那么它就不能作为左值使用,如(a>b?1:b) = 3 非法。
引用:
C++中的引用:一个已经定义的变量的别名。 Type var , Type & name = var; 普通引用在声明时必须用其他的变量进行初始化。引用作为函数参数声明时不进行初始化。
const 修饰引用:const 使引用拥有只读属性,但是变量本身还是原来的属性。
当使用常量对const 引用进行初始化时,编译器会给常量分配空间,并将引用名命名为这段空间的别名。不能给普通引用赋值为常量,但是可以给常引用赋值为常量。此时常引用是只读的,除了在定义时,不能给它赋值。因此用一个常引用可以构成一个只读的变量,如 const int & a = 10 a是一个只读变量。
引用在C++ 的内部实现是一个常指针:type & name ßàtype* const name。因此引用拥有一个4字节的空间。
引用作为函数返回值:返回局部变量的引用时,引用不能作为左值,也不能用它初始化其他引用,但是如果引用时静态的或者全局变量的引用时就可以。
C++ 函数探幽:
内联函数:inline int function(…), 内联函数可以替代宏代码片段,在编译时将函数体直接替代函数被调用的地方,这样就减少了普通函数被调用时 的开销(压栈,跳转等),但是内联函数本质上还是一个函数,不同于宏代码片段。内联函数声明符inline 必须要和函数定义结合在一起,不能放在声明处,否则编译器忽略内联请求。 虽然内联函数省时省空间,
但是编译器不一定准许函数的内联请求,当C++编译器不允许内联请求时会将内联函数当做普通函数处理。
默认参数: C++中可以在函数声明时为参数提供一个默认值,当函数调用时没有提供这个参数的值,编译器会自动用默认值代替。但是在函数定义时就不在指定默认参数值。默认参数有如下规则:
只有参数列表后面的部分参数才可以提供默认参数值,一但在一个函数调用中开始使用默认参数,那么这个参数后的所有参数都必须使用默认参数,因此从开始使用默认参数的使用开始都后面的参数都要提供默认参数,否则编译器将报错。总之,在函数声明时,如果一个参数开始提供默认参数,那么后面的所有参数都要提供默认参数;在调用函数时,如果开始省略参数,那么后面所有参数都使用默认参数。
函数占位参数:占位参数是在函数定义时只有类型声明,没有参数名声明的参数。一般情况下函数体内部无法使用占位参数。但是在调用时必须提供完整的参数个数。可以给占位参数提供默认参数。意义:为函数的后续版本的扩展埋下伏笔;兼容C语言中的不规范写法。
函数重载:简单来说函数重载就是用同一个函数名来定义不同的函数。那编译器是如何区分这些函数的呢?事实上,编译器是通过参数列表来区分重载了的函数。即重载函数拥有不同的参数列表。不同的参数列表包括参数个数不同、参数类型不同、参数顺序不同,即满足上述三个条件之一就能构成重载函数。函数重载在构造函数中是非常有用的。
当函数默认参数遇上函数重载会发生什么神奇的情况?假设这样的情况:程序当中定义两个重载函数,其中一个函数有一个默认参数,在主函数调用这个函数。能不能编译过呢?
经过编译器的验证,当函数默认参数遇上函数重载,编译时没有问题的,但是调用时会发生函数二义性的错误。因此在程序中不能同时使用函数默认参数和函数重载。
编译器调用重载函数的准则:
l 将所有的同名函数作为候选者
l 尝试寻可行的候选函数
& 精确匹配实参
& 通过默认参数匹配实参
& 通过默认类型转换匹配实参
molloc函数 l 匹配失败
& 最终到的可行候选函数不唯一,出现二义性,编译失败
& 无法匹配所有候选者,函数未定义,编译失败
注意:重载函数与返回值类型没有半毛钱关系。
当重载函数赋值给函数指针时发生:
1).根据重载规则挑选与函数指针参数列表一致的候选者
2).严格匹匹配候选者的`函数类型与函数指针的函数类型
只有上述两个不步骤都成功时才能匹配成功,成功调用正确的函数。
C 与 C++ 互相调用:可以使用extern关键字强制让C++编译器对代码使用C的方式进行编译。如 extern “C” { content}
使用如下处理统一处理: __cplusplus 是C++编译器内置的标准宏定义,让C代码既可以通过C编译器的编译,也可以在C++ 编译器中以C方式编译。
#ifdef __cplusplus
extern “C”{
#endif
//函数声明或者函数定义
#ifdef __cplusplus
}
#endif
C++ 新关键字:
new 和delete 动态内存分配和释放
变量申请 数组申请
type* pointer = new type; type* pointer = new type[N]; //申请内存
//……. //……. //使用内存
delete pointer delete[] pointer //释放内存
可以看出,new出来的内存空间不像普通变量那样有一个别名,只有一个地址赋给指针,访问都必须通过指针。
new 与 malloc 函数的区别:
l malloc 是C库提供的函数,new关键字是C++ 的一部分
l new 以具体类型为单位进行内存分配,malloc只能以字节为单位进行内存分配
l new 在申请单个类型变量时可以进行初始化,malloc 不具备初始化的特性
名称空间(namespace) :
C语言中所有的全局标识符共享同一个作用域:全局作用域,C++将全局作用域分成不同的部分,每个部分就是一命名空间,不同命名空间里的标识符可以同名而不会发生冲突,并且命名空间可以嵌套。值得注意的是全局作用域也叫默认命名空间。
命名空间的使用:
l 使用整个命名空间:using namespace name;
l 使用命名空间中的变量: using name ::variable
l 使用默认命名空间 :: variable
类的静态成员:静态成员函数+静态成员变量
类的静态成员变量:存储在全局数据区、不依赖于任何一个对象的类成员变量。
语法规则:type classname ::varname
类的静态成员函数:
语法规则 : 加上static 修饰符
v 在C++中可以定义静态成员变量和静态成员函数
v 静态成员属于整个类所有,不需要依赖任何对象
v 可以通过类名直接访问public静态成员
v 可以通过对象名访问public静态成员
v 静态成员函数可以直接访问静态成员变量
定义静态成员变量:
à在定义类时通过static 修饰成员成员变量可以将变量定义成静态成员变量
à静态成员变量不依赖任何对象,需要在类的定义外面单独分配空间:
type Classname::Varname;
静态成员函数的定义:
è 在定义时直接通过static 关键字修饰,其他的部分与普通的成员函数定义相同。
注意:C++ 类对象中的成员函数和成员变量是分开存储的
à成员变量:普通的成员变量存储在对象中,跟struct 变量有相同的内存分布和字节对齐方式;静态成员变量:存储在全局数据区;
à成员函数:存储于代码段中
静态成员函数和普通成员函数的区别:
l 静态成员函数不包含指向具体对象的指针 this, 但是普通成员函数包含有一个指向对象本身的指针:this 指针
继承:子类拥有父类的所有成员函数和成员变量、子类就是一种特殊的父类、子类对象可以当做父类对象使用、子类拥有父类没有的方法。
C++中的访问级别与继承:
public 继承:父类成员在子类中保持原有的访问级别
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论