Effecvtive C++笔记:让自己习惯C++
条款01:视C++为一个语言联绑
C++的四个语言层次:
- C:C++是以C为基础的。基本数据类型、语句、预处理器、数组、指针等统统来自C。
- Oject-Oriented C++:面向对象这一特性包含了:类,封装,继承,多态,虚函数等
- Template C++:C++的泛型编程能力。
- STL:一个标准的template库,里面介绍了容器、迭代器、算法以及函数对象等模板类和模板函数。
综述:C++并不是一个带有一组守则的一体语言:它是从四个次语言组成的联绑政府,每个次语言都有自己的规约。
条款02:尽量以const,enum,inline替换#define
对于单纯常量,最好以const对象或enums替换#define。
对于形似函数的宏,最好改用inline函数替换#define
条款03:尽可能使用const
STL的迭代器是以指针为根据塑模出来,所以迭代器的作用就像个T*的指针。声明迭代器为const就像声明指针为const一样(即声明一个T*const指针),表示这个迭代器不得指向不同的东西,但它所指的东西的值是可以改动的。如果希望迭代器所指的东西是不可被改动的,需要的是const_iterator。
vector<int> vec;
const vector<int>::iterator = vec.begin();
*iter = ; // 没问题,改变iter所指物
++iter; // 错误!iter是const
vector<int>::const_iterator cIter = vec.begin();
*cIter = ; // 错误!*cIter是const
++cIter; // 没问题,改变cIter
请记住
- 将某些东西声明为const可帮助编译器侦测出错误用法。const可被施加于任何作用哉内的对象、函数参数、函数返回类型、成员函数本体。
- 编译器强制实施bitwise constness,但你编写程序时应该使用“概念上的常量性”。
- 当const和non-const成员函数有着实质等价的实现时,令non-const版本调用const版本可以避免代码重复。
条款04:确定对象被使用前已先被初始化
类的构造函数的次序是先执行构造函数初始化列表,初始化所有成员变量,然后再执行构造函数体,构造函数体内的成员赋值已经不属于初始化的范畴,成员都是用拷贝赋值。
如果类没有初始化列表,则类会先执行默认构造函数,构造出所有成员变量后,再执行函数体内的拷贝赋值。
C++类的成员初始化是有着明显的次序的,一般是基类的成员先初始化,然后派生类的成员按定义的顺序初始化。所以类的构造函数初始化列表上的初始化顺序跟类真实的成员初始化顺序是没有关系的。
“不同编译单元内定义之non-local static对象”
static对象,其寿命从被构造出来直到程序结束为止。
函数内的static对象称为local static对象(因为它们对函数而言是local),其他static对象称为non-local static对象。程序结束时static对象会被自动销毁,也就是它们的析构函数会在main()结束时被自动调用。
当我们的某个编译单元内的某个non-local static对象的初始化动作使用了另一编译单元的某个non-local static对象,它所用到的这个对象可以尚未被初始化。C++关于定义于不同编译单元内的non-local static对象的初始化次序并无明确定义。
比如在a.cpp里我们定义一个类,一个该类的对象
class FileSystem
{
public:
size_t numDisks()const;
};
extern FileSystem tfs;
现在同一个项目下的b.cpp文件中有一个类,类构造函数用到了tfs对象。
class Directory
{
public:
Directory(params);
};
Directory::Directory(params)
{
size_t disks = tfs.numDisks();
}
现在如果我们创建了一个Directory对象
Directory tempDir(params);
上面的代码就可能会出问题,除非能保证tfs在tempDir之前先初始化,否则tempDir的构造函数会用到尚未初始化的tfs。
解决方案:
C++保证,函数内的local static对象会在该函数被调用期间,首次遇到该对象的定义的时候被初始化。
所以如我们把tfs和tempDir设计为一个函数,函数返回该类的一个static对象引用就可以解决问题了。
所以我们可以改写上面的代码:
FileSystem& tfs()
{
static FileSystem fs;
return fs;
} Directory& tempDir()
{
static Directory td;
return td;
}
请记住
- 为内置型对象进行手工初始化,因为C++不保证初始化它们。
- 构造函数最好使用成员初始化列表,而不要在函数体内使用赋值操作。初始列表列出的成员变量,其排列次序应该和它们在class中的声明次序相同。
- 为免除“跨编译单元之初始化次序”问题,请以local static对象替换non-local static对象。
Effecvtive C++笔记:让自己习惯C++的更多相关文章
- MATLAB菜鸟入门笔记【编程习惯】
1.编程标记模板 % Script file:temp_conversion.m % % Purepose: % To convert an input temperature from d ...
- 【原】javascript笔记之Array方法forEach&map&filter&some&every&reduce&reduceRight
做前端有多年了,看过不少技术文章,学了新的技术,但更新迭代快的大前端,庞大的知识库,很多学过就忘记了,特别在项目紧急的条件下,哪怕心中隐隐约约有学过一个方法,但会下意识的使用旧的方法去解决,多年前ES ...
- [Ting's笔记Day4]将Ruby on Rails项目部署到Heroku
今天想笔记的是把自己写的Ruby on Rails项目部署(Deploy)到Heroku! Heroku是Salesforce公司旗下的云端服务商,支持多种程序语言像是Ruby,PHP,Python等 ...
- Android新建项目手动添加Layout布局
前言: 这是看<第一行代码>学习到的第一章,之前使用Eclipse创建Android项目都是自动生成MainActivity.java文件和layout文件夹下的activity_main ...
- 一年三篇IF大于7的牛人告诉你怎么写SCI
一年三篇IF大于7的牛人告诉你怎么写SCI 1 研究生必备四本 俗话说好记性不如烂笔头,所以一定要首先养成做笔记的好习惯!作为研究生下面这几个本子是必不可少的: 1.实验记录本(包括试验准备本),这当 ...
- SAS学习︱逻辑库、数据集创建与查看、数据库链接(SAS与R的code对照)
每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 入门学习一周,开始写学习笔记.用习惯R之后,发 ...
- PHP 入门学习教程及进阶(源于知乎网友的智慧)
思过崖历程: 自学的动机.自学的技巧.自学的目标三个方面描述学习PHP的经历 一.自学的动机: 一定要有浓厚的兴趣,兴趣是最后的老师,可以在你迷茫的时候不断地支撑着你走下去. 自学不是为了工作,不是为 ...
- 从零开始一起学习SLAM | 理解图优化,一步步带你看懂g2o代码
首发于公众号:计算机视觉life 旗下知识星球「从零开始学习SLAM」 这可能是最清晰讲解g2o代码框架的文章 理解图优化,一步步带你看懂g2o框架 小白:师兄师兄,最近我在看SLAM的优化算法,有种 ...
- 聊聊我怎么系统学习Linux技能并快速提高的
随着电子信息科技时代的发展,学会使用计算机在我们的生活中成为了必不可少的一项技能.而作为计算机中的三大操作系统之一的Linux更是饱受计算机爱好者们的喜爱.今天我们就来和大家一起聊一聊Linux操作系 ...
随机推荐
- javascript 规范
关于变量及方法等的命名,没有硬性规定,但是为了规范,遵循一些约定还是有必要的. 变量定义: 用var 关键字将要使用的变量定义在代码开头,变量间用分号隔开. 原因有二: 一是便于理解,知道下面的代码会 ...
- 重写UIPageControl实现自定义按钮
有时候UIPageControl需要用到白色的背景, 那么会导致上面的点按钮看不见或不清楚,我们可以通过继承该类重写函数来更换点按钮的图片现实.实现思路如下.新建类继承UIPageControl : ...
- LinkedHashMap实现LRU算法
LinkedHashMap特别有意思,它不仅仅是在HashMap上增加Entry的双向链接,它更能借助此特性实现保证Iterator迭代按照插入顺序(以insert模式创建LinkedHashMap) ...
- 洛谷P2014 TYVJ1051 选课
题目描述 在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习.现在有N门功课,每门课有个学分,每门课有一 ...
- mybatis-spring从1.1升级到1.2所带来的dao层级的编写问题
我们公司的项目使用spring+mybatis组合.所以就必须得使用mybatis-spring了.所以此处就昨日mybatis-spring从1.1升级到1.2所带来的dao层级的编写问题,做了一个 ...
- AppStore占坑注意事项
AppStore占坑注意事项 我们会提前在AppStore(iTunesConnect)里注册一些应用名称,以满足未来业务需要和防止恶意注册,其中有一些需要注意的事情,整理如下: 倒计时180天 为了 ...
- html5+监听设备加速度变化信息
watchAcceleration 监听设备加速度变化信息 Number plus.accelerometer.watchAcceleration( successCB, errorCB, optio ...
- 初学JDBC,防SQL注入简单示例
在JDBC简单封装的基础上实现 public class UserDao{ public static void testGetUser(String userName) throws Excepti ...
- UVa OJ 197 - Cube (立方体)
Time limit: 30.000 seconds限时30.000秒 Problem问题 There was once a 3 by 3 by 3 cube built of 27 smaller ...
- Redis Cluster 理论知识
http://www.ttlsa.com/redis/redis-cluster-theoretical-knowledge/ Redis 集群的 TCP 端口(Redis Cluster TCP p ...