Effective C++ 笔记1

本文基于《Effective C++》一书,整理了关于C++编程中的关键优化策略,包括视C++为语言联邦、使用const、enum和inline替代#define、确保对象初始化等核心内容。文章详细解释了如何通过合理利用C++特性,提高代码质量与效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 本文内容基本来自于《Effective C++》一书,为学习后的笔记,以便温故。


《Effective C++ 》第 1节  让自己习惯C++

(1)条款01  视C++为一个语言联邦

理解C++,必须认识其主要的次语言。共有四个:

C,Object-Orented C++, Template C++, STL

(2)条款02 尽量以const, enum, inline替换#define

     如:#define  VALUE  1,该记号名称可能没有进入记号表,所以当你在使用该变量产生一个编译错误的时候,编译器的错误信息中会提到 1 这个数值,但是没有VALUE,这使得你无法准确的定位到错误。而是用const声明常量就会解决这个问题。

     class GamePlayer{

     static const int num = 5;

     int  scores[num];

};

在旧式编译器中也许不支持上述语法,他们不允许static成员在其声明式上获得初值。如果你的编译器不支持在声明式上赋值,可以再class的实现文件内进行定义。如:

class Test{

 static const int num; //在Test的头文件中声明

};

const int Test::num = 5; //在Test实现文件内

但是在GamePlayer类中,你必须要在声明数组scores时,给他一个确定的数值。这种情况下,可以使用“the enum hack“补偿做法。其理论基础是:“一个属于枚举类型的数值可权充ints来使用”,于是GamePlayer可定义如下:

class GamePlayer{

  enum{num = 5};

  int sorces[num];

};

对于enum hack方法来说,它的行为比较像#define,但是它能够计入记号表,能够避免编译错误不好定位的问题,并且他不像const 常量,取一个const的值是可以的,但是不可以取一个enum的地址。所以当你不想让别人获得一个pointer或者reference指向你的某个整数常量,enum可以帮你实现这个约束

使用#define实现类似于函数的宏,不会招致函数调用带来的额外的开销。但是使用这种宏经常会出现各种陷阱和麻烦。所以使用inline来代替类似于函数的这种宏。

(3)条款03:尽可能使用const

将某些东西声明为const可帮助编译器侦测出错用法,const可被施加于任何作用域内的对象,函数参数,函数返回类型,成员函数本体

编译器强制实施bitwiseconstness,但是你编写程序时应该使用“概念上的常量性”

当const和non-const成员函数有着实质等价的实现时,令non-const版本调用const版本可避免代码重复。

(4)条款04:确定对象使用前已先被初始化

     读取未初始化的对象会导致不明确的行为,在某些平台上,仅仅只是读取未初始化的值,就可能使得程序终止。

     所以在使用任何类型前都应该首先初始化,无论是内置类型还是自定义类型。对于无任何成员的内置类型,我们需要手工完成初始化,对于自定义类型,初始化的任务落在了构造函数中。另外,还需要了解赋值和初始化的区别。例如:

class Test{

 int  x;

 stringy;

Test(int x, string y){}

};

Test:Test(){

 this->x= x; //这是赋值操作,而不是初始化操作

this->y = y;

}

C++规定,对象的成员变量的初始化动作发生在进入构造函数本体之前。如Test的成员函数的初始化发生在default构造函数调用之前。Test构造函数的最佳写法是,使用所谓的member initialization list替换赋值动作:

Test::Test(int  x,string  y):x(x),y(y)  //这实现了成员变量的初始化。

{

  //do other thing

}

这样使得成员变量在初始化的时候就设置了相对应的值,而不需要在经过一次赋值操作。提高了效率。

C++有着十分固定的“成员初始化次序”。基类总是更早于子类的初始化,而class成员变量的初始化总是以其声明的次序初始化。

C++对于“定义在不同的编译单元内的non-localstatic对象的初始化次序并无明确的定义”。解决这种问题的办法是将每个non-local static对象搬到自己的专属函数内。这些函数返回一个reference,用户调用这些static函数,而不直接涉及到这些对象。这种手法的基础在于:C++保证,函数内的local static对象会在“该函数被调用期间,首次遇到该对象”时被初始化。单例模式使用的就是这种手法。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值