Effective C++ 第一章:让自己习惯C++
Effective C++ 第一章:让自己习惯C++
引言
最近在阅读这本《effective C++ 改善程序与设计的55个具体做法》这本书,为了以后忘记的时候回顾,写一些笔记,每次笔记大概记录一个章节的内容。
条款1.视C++为一个语言联邦
C++最早只是C语言的扩充,在C基础上加上了面向对象特性,但是发展了很多年后,变的庞大了很多。
现在的C++是一个多重范式编程语言,支持面向过程,面向对象,函数形式,泛型形式,元编程形式。
至少记住这四项,C,object-orented-C++,template-C++,STL,分别是C语言,面向对象的C++,C++模板,STL库(template程序库)。
条款2.尽量以enum,const,inline替换掉define
宁可以编译器替换掉预处理器
情况1
#define ASPECT_RATIO 1.653
这个记号名称可能会在编译器处理源码前被预处理器移动走了,没有进入记号表内(symbol table),于是你运行这个常量就会获得一个编译错误信息而浪费时间。
解决方法
const double AspectRatio = 1.653
const肯定会被编译器看到,当然会进入记号表内,防止编译问题。
情况2
你想创建一个class专属常量
class cl{
private:
static const int NumTurns=5; //常量的声明式
int arr[NumTurns];
}
c++要求对你所使用的都提供一个定义式,但上面的class专属常量并且static就可以例外。如果你想要获取常量的内存地址,或者有一些编译器坚持需要定义式,你需要提供定义式如下:
const int cl::NumTurns; //NumTurns的定义
如果你不想让你class专属常量内存地址被访问,你可以用enum类型去替代
class cl{
private:
enum {NumTurns=5}; //让NumTurns成为5的一个记号名称
int arr[NumTurns];
}
情况3
define创建的宏函数
template<class T>
T f(T x)
{
return x;
}
#define CALL_WITH_MAX(a,b) f((a)>(b) ? (a) : (b))
上面的宏函数作用是比较两个数大小,并且返回大的数字,但是这个宏函数很容易产生意外。
int a=5,b=0;
std::cout<<a<<" "<<b<<std::endl; //5 0
CALL_WITH_MAX(++a,b);
std::cout<<a<<" "<<b<<std::endl; //7 0
CALL_WITH_MAX(++a,b+20);
std::cout<<a<<" "<<b<<std::endl; //8 0
上面的a在和比较的时候自增了两次,为了避免这种bug,我们换成inline模板函数来代替它
template<class T>
T f(T x)
{
return x;
}
template<typename T>
inline void callWithMax(const T& a,const T& b)
{
f(a>b ? a : b);
}
int a=5,b=0;
std::cout<<a<<" "<<b<<std::endl; //5 0
CALL_WITH_MAX(++a,b);
std::cout<<a<<" "<<b<<std::endl; //6 0
CALL_WITH_MAX(++a,b+20);
std::cout<<a<<" "<<b<<std::endl; //7 0
对于单纯常量,最好以const对象或者enums代替#defines
对于形似函数的宏,最好改用inline函数代替#defines
条款3.尽可能使用const
const允许你使用语义约束,告诉编译器这个值保持不变。
情景1
char str[] = "hello";
char *p = str; //不是const指针,也不是const数据
const char *p = str; //不是const指针,是const数据
char const *p=str; //是const指针,不是const数据
const char const *p=str; //是const指针,是const数据
const的规则,const在左边,代表了指针指向的数据是const,const在右边,代表了指针本身是const。
情景2
class cl{
public:
...//省略构造函数析构函数
char& operator[](std::size_t position)const //代表const成员函数
{
return pText[position];
}
...
private:
char *pText;
};
上面的const成员函数看似没有修改class内部成员,其实已经发生了泄漏。
const cl class_cl("hello");
char *cp=&class_cl[0];
cp='J'; //这里修改了const的数据内容
所以请记得给上面的const成员函数加上const,并且记住const成员函数承诺任何时候都不修改其对象的逻辑状态。
条款4 确定对象被使用前已经被初始化
读取未初始化的值可能导致不明确的行为,甚至在一些平台上会导致你的程序终止。
弄清楚赋值和初始化的区别:
int x=0; //初始化
x=1; //赋值
在class的构造函数中,初始化和赋值容易搞混淆
class cl{
...
cl(int &data):num(data){} //初始化成员变量
cl(int *p)
{
num=*p;//这里num先被默认初始化一个值,然后被赋值*p
}
...
private:
int num;
}
使用初始化列表比赋值的效率会更高,只调用了一次构造函数,而不是先调用默认构造函数再赋值。
请以local static对象代替 non-local static对象
在C++中,local static对象和non-local static对象的主要区别在于它们的生存期和作用域。
Local static对象是指在函数内部声明并使用static关键字修饰的变量或对象。它们在函数第一次被调用时创建,并一直存在于函数的整个生命周期内,直到函数结束时才被销毁。Local static对象的作用域仅限于其所在的函数,不能在其他函数中访问。
Non-local static对象是指在函数外部声明并使用static关键字修饰的变量或对象。它们在程序启动时创建,并一直存在于程序的整个生命周期内,直到程序结束时才被销毁。Non-local static对象的作用域是全局的,可以在任何函数中访问。
以local static对象代替non-local static对象意味着将non-local static对象改为在函数内部声明并使用static关键字修饰。这样做有以下几个优点:
提高代码的局部性:Local static对象的作用域仅限于其所在的函数,可以提高代码的局部性,使代码更容易理解和维护。
减少内存占用:Non-local static对象在程序的整个生命周期内都存在,即使在不再使用时也无法释放内存。而local static对象在函数结束后就会被销毁,可以减少内存占用。
提高安全性:Non-local static对象可以在任何函数中访问,这可能会导致意外修改或污染。而local static对象只能在函数内部访问,可以提高安全性。
当然,以local static对象代替non-local static对象也有一些缺点:增加了代码的复杂度 ,降低了代码的效率。
// Non-local static object
static int global_count = 0;
void foo() {
global_count++;
// ...
}
// Local static object
void bar() {
static int local_count = 0;
local_count++;
// ...
}
在这个例子中,global_count是一个non-local static对象,在任何函数中都可以访问。而local_count是一个local static对象,只能在bar()函数中访问。
在foo()函数中,每次调用都会增加global_count的值。而在bar()函数中,每次调用只会增加local_count的值。
如果foo()函数被频繁调用,那么global_count的值会迅速增长,可能会导致内存占用过高。而bar()函数的local_count值只会在一个函数内累加,不会影响其他函数。
Effective C++ 第一章:让自己习惯C++的更多相关文章
- Effective c++ 第一章 让自己习惯C++
条款 01:c++是一个语言联邦而不是一种单一的语言, 它包括: 1.C语言:没有模版.没有异常.没有重载…… 2.Object-Oriented C++:class.析构函数.构造函数.封装.继承. ...
- Effective java第一章引言
菜鸟一枚,开始读第一本书<Effective Java>(第二版)~ 看引言就有好多名词不懂(>_<) 导出的API由所有可在定义该API的包之外访问的API元素组成.一个包的 ...
- 【C++】《Effective C++》第一章
第一章 让自己习惯C++ C++是一个威力强大的语言,带着众多特性,但是在你可以驾驭其威力并有效运用其特性之前,你必须先习惯C++的办事方式. 条款01:视C++为一个语言联邦 如今的C++已经是个多 ...
- 《Effective C++》第1章 让自己习惯C++-读书笔记
章节回顾: <Effective C++>第1章 让自己习惯C++-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(1)-读书笔记 <Effecti ...
- Effective JavaScript :第一章
第一章 一.严格模式与非严格模式 1.在程序中启用严格模式的方式是在程序的最开始增加一个特定的字符串字面量: ‘use strict’ 同样可以在函数体的开始处加入这句指令以启用该函数的严格模式. f ...
- Stealth视频教程学习笔记(第一章)
Stealth视频教程学习笔记(第一章) 本文是对Unity官方视频教程Stealth的学习笔记.在此之前,本人整理了Stealth视频的英文字幕,并放到了优酷上.本文将分别对各个视频进行学习总结,提 ...
- 【USACO】第一章总结
做了大半个月,终于把第一章做完了 有的题遇到了不小的坎儿,看着网上一群高中生都做得那么好,心理还是有些小郁闷的.不禁感慨我过去的四年真是虚度啊.总结一下第一章学习到的知识吧. ①闰年判断 int is ...
- JAVA学习之Ecplise IDE 使用技巧(1)第一章:我的地盘我做主,工作空间
麦子学院/Andriod应用开发/第一阶段 Android 学前准备 第三课:Eclipse IDE 使用技巧 由马一鸣老师讲解.感谢麦子学院免费开放这部分视频资源. Eclipse由IBM开发的,2 ...
- Laxcus大数据管理系统2.0(2)- 第一章 基础概述 1.1 基于现状的一些思考
第一章 基础概述 1.1 基于现状的一些思考 在过去十几年里,随着互联网产业的普及和高速发展,各种格式的互联网数据也呈现爆炸性增长之势.与此同时,在数据应用的另一个重要领域:商业和科学计算,在各种新兴 ...
- 翻译学python---《Learn Python the hard Way》---第一章 绪论
打算学习python,但是又不想单纯地看书或是写个小项目,干脆引入很流行的翻译学习法来学习吧- 在论坛上看到了国外的一本<Learn Python the hard Way> ...
随机推荐
- 手把手教学构建证券知识图谱/知识库(含码源):网页获取信息、设计图谱、Cypher查询、Neo4j关系可视化展示
手把手教学构建证券知识图谱/知识库(含码源):网页获取信息.设计图谱.Cypher查询.Neo4j关系可视化展示 demo展示: 代码结构 stock-knowledge-graph/ ├── __i ...
- 数据挖掘机器学习[五]---汽车交易价格预测详细版本{模型融合(Stacking、Blending、Bagging和Boosting)}
题目出自阿里天池赛题链接:零基础入门数据挖掘 - 二手车交易价格预测-天池大赛-阿里云天池 相关文章: 特征工程详解及实战项目[参考] 数据挖掘---汽车车交易价格预测[一](测评指标:EDA) 数据 ...
- 【一】tensorflow【cpu/gpu、cuda、cudnn】全网最详细安装、常用python镜像源、tensorflow 深度学习强化学习教学
相关文章: [一]tensorflow安装.常用python镜像源.tensorflow 深度学习强化学习教学 [二]tensorflow调试报错.tensorflow 深度学习强化学习教学 [三]t ...
- 【一】gym环境安装以及安装遇到的错误解决
相关文章: [一]gym环境安装以及安装遇到的错误解决 [二]gym初次入门一学就会-简明教程 [三]gym简单画图 [四]gym搭建自己的环境,全网最详细版本,3分钟你就学会了! [五]gym搭建自 ...
- 3.1 C/C++ 使用字符与指针
C/C++语言是一种通用的编程语言,具有高效.灵活和可移植等特点.C语言主要用于系统编程,如操作系统.编译器.数据库等:C语言是C语言的扩展,增加了面向对象编程的特性,适用于大型软件系统.图形用户界面 ...
- CE修改器入门:查找共享代码
本关我们将学习共享代码,在C语言中角色属性都是以结构体的方式进行存储的,而结构体所存储的信息都是连续性的,这一关我们将会解释如何处理游戏中的共用代码,这种代码是通用在除了自己以外的其他同类型对像上的 ...
- 《Mybatis 手撸专栏》第2章:创建简单的映射器代理工厂
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 着急和快,是最大的障碍! 慢下来,慢下来,只有慢下来,你才能看到更全的信息,才能学到 ...
- webrtc终极版(题外话)辛苦写文章分享,竟然遇到喷子狂喷,写篇文章回怼下,顺便发表下面对喷子的处理方式
webrtc终极版(题外话)辛苦写文章分享,竟然遇到喷子狂喷,写篇文章回怼下,顺便发表下面对喷子的处理方式 第一篇文章发过后,出人意料的是,收到了博客园某一位用户的狂喷[注:本系列文章会同步发布到cs ...
- Label的背景色
Label的背景色是 color属性,但是这个属性是 必须 Transparent 为 false的时候 才生效,否则不生效
- OGG-将PostgreSQL通过OGG_BigData同步到Kafka后数据存在8小时时间差
问题描述: 将PostgreSQL通过OGG_BigData同步到Kafka后数据存在8小时时间差. 问题原因: kafka.properties中的参数goldengate.userexit.tim ...