C++关键字实用经验

文章内容均抄自    刘光《C++程序员不可不知的101条实用经验

1.尽可能多地使用const
①    int const a 和 const int a等价,表示一个整型常量
②    int const * a 和 const int * a等价
const在*的左边,说明指针所指向的对象是常值,如果指向的对象是常值,const在类型的前面和后面都一样
③    int * const a
const在*的右边,说明指针是恒值,指针所指向的地址不可更改
④    const int * conat a
const在*的左边和右边,说明指针是恒值,指向的对象是常量
const在函数声明中的位置
(1)函数参数列表使用const
表示函数调用传进来的参数是一个常量或常指针
(2)函数返回值声明为const
表示函数返回的是一个常值,不能够被修改
(3)const成员函数
按位恒定:当且仅当一个成员函数对所有的数据成员都不做出改动时,才需要将此函数声明为const
逻辑恒定:一个const的成员函数可能对其调用的对象内部做出改动,需要对可变成员加mutable关键字
⑥尽量用const常量替换#define常量定义
const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干个拷贝,所以使用const常量可以节省内存

2.volatile和mutable用在何处
①mutable关键字(C++特有)
如果在const成员函数中修改一个成员变量的值,那么需要将这个成员变量修饰为mutable,即mutable修饰的成员变量不受const成员方法限制。
②volatile关键字(C/C++都有)
定义为volatile的变量,说明这个变量可以被意想不到地修改,编译器就会去假设这个变量的值,精确地说,编译器在用到这个变量时必须每次都小心第从内存中重新读取这个变量的值,而不是使用保存在寄存器的备份
(1)作为指令关键字,volatile具有确保本条指令不会因编译器的优化而省略的功能
(2)使用volatile关键字修饰的类型变量可以被未知因素修改。
(3)对于volatile类型的变量,系统在用它的时候都是直接从对应的内存中提取
使用场合:
(1)中断服务程序中修改的供其他程序检测的变量需要加volatile
(2)多任务环境下,各任务间共享的标志应该加volatile
(3)并行设备,存储器映射的硬件寄存器通常也要加volatile说明
讨论:一个参数可以是const又是volatil。典型的例子是只读的状态寄存器,它既是volatile,因为它能被意想不到的改变,它又是const,因为程序不应该试图去修改它

3.尽量用new/delete代替malloc/free
使用区别:
(1)new/delete在管理内存的同时会调用类的构造函数和析构函数,而malloc/free仅仅实现了内存的分配和释放,没有调用类的构造函数和析构函数
(2)new/delete是C++语言的运算符关键字,而malloc/free是C/C++语言的标准库函数
(3)malloc函数返回的类型是void*,任何类型的指针都可以转换成void*,但最后在前面进行强制转换。而是用new返回的类型就是需要的数据类型
(4)new申请内存失败时,会调用new_handler处理函数,而malloc申请内存失败时仅返回NULL,不会进行善后处理
其实new有三种不同的形态,分别是new operator,operator new和placement new。通常说明的是new operator,执行过程分为3步
①通过operator new申请内存
②使用placement new调用构造函数(简单类型忽略此步骤)
③返回内存指针

4.使用new/delete时要采用相同的形式
当使用new动态生成一个对象时,有两件事发生
(1)对象内存的分配(这一过程通过名为operator new的函数实现)
(2)针对此内存会有一个(或更多)构造函数被调用
当使用delete释放对象内存时同样也会有两件事发生
(1)针对此内存会有一个(或更多)析构函数被调用
(2)内存被释放(通过名为operator delete的函数)
请谨记:如果使用new[],则释放内存时使用delete[],如果未使用new[],则释放内存时不能使用delete[]

5.sizeof和对象的大小
sizeof的使用:
(1)int i = 0;sizeof(i)或者是sizeof i
(2)sizeof(int),若写成sizeof int则会报错
注意:
(1)对内置数据类型做sizeof运算时,unsigned关键字不会影响内置类型的取值
(2)只要是指针,sizeof的结果都是4
(3)函数类型以其返回值的类型作为自身类型。注意不能对返回void的函数进行sizeof取值,也不能对函数指针(函数名)进行sizeof取值
(4)空结构体和类取sizeof运算的结果是1不是0,是编译器为了办证空结构体或类存在而专门分配的一个字节
(5)不含继承和static成员变量的类的大小
计算规则同结构体,只计算成员变量的大小,不计算成员函数的
(6)包含继承和static成员变量的类的大小
在单继承情况下,只要class中存在virtual函数,在编译时编译器就会自动插入一个指向虚函数表的指针vptr(大小为4个字节,只算一次);因为静态成员是分配在全局静态区,sizeof运算不计入静态成员变量的大小。

6.谨慎使用static
指变量或函数在可执行程序中开始执行时生成,程序关闭时释放消失,在程序的执行过程中不会消失
(1)静态局部变量
存储在全局静态区,在程序的整个运行期间都不会释放,在初次运行时进行初始化工作,且只初始化一次,若不赋初值,则编译器会自动赋初值0或空字符,由于局部static变量导致函数具有不可重入性,存在线程安全问题。
(2)静态全局变量/函数
为了限制函数和变量的作用域,在函数或变量前加static使得函数成为静态函数,限定作用域只能在本文件内,不能被其他文件访问。
(3)静态成员变量/函数
①静态成员初始化的格式为:<数据类型><类名>::<静态数据成员>=<值>,且只能在类外初始化
②声明两个类对象时,修改一个对象中的静态变量,另一个对象的静态变量也会被修改,静态成员变量在程序中只有一份拷贝,有该类型的所有对象共享访问
静态成员函数不含this指针(普通成员函数都会隐含一个this指针),静态成员函数无法访问类对象的非静态成员变量和非静态成员函数,只能调用静态成员函数
④静态成员函数的调用格式 <类名>::<静态成员函数名>(<参数表>)














评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值