条款一:视C++为一个语言联邦


学习C++半个月了,学了他的面向过程编程,面向对象编程(封装性,继承性,多态性),template泛型编程,开始只是觉得C++基础是面向对象,但是学了这么多块开始有点迷糊,而条款一很好的解释了我的迷惑。

“C++已经是个多重范型编程语言(multiparadigm programming language),一个同时支持过程形式,面向对象形式,泛型形式,元编程形式的语言。”

而在这么多无敌的工具下,我们如何去理解这么一个语言呢?

“将C++视为有相关语言组成的联邦而非单一的语言(相关语言称之为“次语言”)” 面对每个次语言都有自己的守则(对一些工具的选择)或者通类。

而幸运的是C++中次语言只有四个:

1.C。 说到底C++就是以C为基础的。基础语法(内置数据类型,预处理器,数组,指针)都来自C语言,只不过C++的解法较之C更高级一点。

2.Object-Oriented C++。 :这部分包含类,封装性,继承性,多态性,虚函数,这部分是面向对象设计在C++的直接实施。

3.Template C++。 泛型C++设计,现在的主流设计思想

4.STL。完美的把容器,迭代器,算法,函数对象紧密配合和协调。

当你从某个次语言切换到另外一个次语言时,会导致你的编程守则策略的改变。

比如对参数传递策略的选择上,在内置类型(C-Like)类型而言,pass-by-value(值传递)通常比pass-by-reference更高效(所以不能认为引用传递是最好的),而当你面对是自定义对象或者是Template C++中,pass-by-reference-const会是更好的选择。

所以,总之,对C++的理解分为四个次语言来理解,并且对策略的选择因为次语言的不同去选择。

条款二:尽量以const,enum,inline代替 #define


1.const常量

自从const在C++出现以后,#define 就一直受在排挤,因为他在很多时候存在很多的隐患。因为他不能被分配内存空间,出错的时候很难追踪到错误信息。

(1)常量指针(const pointer)

这是一个比较常见的const话题,比如:

 const int *p;       //
int const *p;      //前面两种形式不一样,但是是同一种。都是指针所指向的变量是修饰为常量
int *const p; //const修饰的是指针变量本身,指针变量本身是常量
const int *const p; //合以上两者

C++在C的进阶:

const char *const authorName = "Scott Meyers";
//string对象通常比他的前辈char*更合适一点。
const std::string authorName("Scott Meyers");

(2)class专属常量

两个条件:该变量是常量,且必须是在类的作用域范围

class GamePlyer
{
private:
static const int NumTurns = ;//这是初始化方式中唯一能在类声明时初始化的方式
int scores[NumTurns]; //使用该变量
};

作者很遗憾的告诉你“然而,你看到的只是声明式而非定义式”

只要你不取地址,你可以声明并且使用它们而无须提供定义式

//定义式
const int GamePlayer::NumTurns; //这里不用给予数值是因为声明时已经获得初值了,所以这里不需要再给予。

#define  是无法创建这样的专属常量的,因为它并不重视作用域,所以导致其不能提供封装性的要求。

2.the enum hack

【1】enum(枚举类型):学习C语言的时候就没有重视这个知识点,好几次,连基本概念都没有搞清楚,现在看到都不知道什么意思,这是个不好的习惯。

枚举类型:如果一个变量只有几种可能的值,则可以用枚举来解决,这在实际生活中很实用。(这也是为什么枚举不倒的原因吧)

enum Weekday{sun,mon,tue,wed,thu,fri,sat};    //声明
enum Weekday workday,weekend; //定义枚举变量
/*
1.在C语言中,enum Weekday是该变量类型,但是在C++中解除了这种麻烦的声明变量名,可以直接使用类型名,不必带上enum
2.{}中的sun,mon,...,sat是枚举元素或者枚举常量。是用户自定义的,也是设计者根据需要命名的,注意这里它虽然是标示符,但是不能当做变量,这里编译器是把它当做常量处理,默认第一个是0,然后顺序下去,mon的值为1...也可以自己认为指定值。后面的顺序加1.
3.枚举也可以做判断比较
if(workday == mon)...
if(workday > sun)...
*/

【2】SM(作者Scott Meyers)enum类型变量有const没有的,

用他的话来说就是:“基于数个理由enum hack值得我们认识”

(1)enum hack的行为某方面比较像#define而不像const,有时候这是我们想要的。

获取一个const的地址是合法的,而获取一个enum的地址是不合法的,通常取一个#define 的地址也是不合法的。当你不像别人通过pointer或者reference指向你的 某个整数常量,enum可以帮助你实现这个约束。并且enum不会浪费不必要的内存分配。

(2)纯粹的为了实用主义

这句话足以让你想去了解enum hack   “事实上,enum hack是template 模板元编程的基础”

并且我最近学习Qt编程,阅读帮助文档几乎随处可以见到枚举类型的编程。

3.inline替换#define函数行为

#define 定义函数行为我用的不多,但是看一些比较牛的大赛里面,C语言的宏定义函数很是厉害,但是这是对于那些大牛而言,因为#define 函数行为实在是存在太多的隐患,因为他是纯粹的替代,并不会处理,而这会导致很多形式上的错误,无法想象,所以,我这里按照SM(作者Scott Meyers)的说法,用inline函数替代这个麻烦的东西。

//一般使用template inline
template<typename T>
inline void callWithMax(const T& a, const T& b)
{
return a>b?a:b;
}

读《effective C++》1的更多相关文章

  1. [已读]编写高质量代码 改善JavaScript程序的188个建议

    吐槽一万遍,买的最后悔的一本,没有之一,大量篇幅抄袭<高性能javascript>,我记得还有部分抄袭<javascript精粹>,<javascript模式>有没 ...

  2. 《编写高质量代码改善JavaScript程序的188个建议》读书笔记

    逗号运算符比较怪异.如    var a =(1,2,3,4);alert(a);// 4      var a = 1,2,3,4;//报错 注意a++和++a的差别,变量在参与运算中不断地变化.v ...

  3. 编写高质量代码改善java程序的151个建议——导航开篇

    2014-05-16 09:08 by Jeff Li 前言 系列文章:[传送门] 下个星期度过这几天的奋战,会抓紧java的进阶学习.听过一句话,大哥说过,你一个月前的代码去看下,慘不忍睹是吧.确实 ...

  4. 编写高质量代码:改善Java程序的151个建议 --[117~128]

    编写高质量代码:改善Java程序的151个建议 --[117~128] Thread 不推荐覆写start方法 先看下Thread源码: public synchronized void start( ...

  5. 编写高质量代码改善C#程序的157个建议——建议150:使用匿名方法、Lambda表达式代替方法

    建议150:使用匿名方法.Lambda表达式代替方法 方法体如果过小(如小于3行),专门为此定义一个方法就会显得过于繁琐.比如: static void SampeMethod() { List< ...

  6. 编写高质量代码改善C#程序的157个建议——建议140:使用默认的访问修饰符

    建议140:使用默认的访问修饰符(我不太赞成作者的这个观点,这样减少的代码基本可以忽略不计,但是,如果把访问修饰符补充完整,反而会使代码更加易读.我认为自己写代码时应该尽量加上访问修饰符,看别人写的代 ...

  7. 编写高质量代码改善C#程序的157个建议——建议25:谨慎集合属性的可写操作

    建议25:谨慎集合属性的可写操作 如果类型的属性中有集合属性,那么应该保证属性对象是由类型本身产生的.如果将属性设置为可写,则会增加抛出异常的几率.一般情况下,如果集合属性没有值,则它返回的Count ...

  8. 编写高质量代码改善C#程序的157个建议——建议9: 习惯重载运算符

    建议9: 习惯重载运算符 在开发过程中,应该习惯于使用微软提供给我们的语法特性.我想每个人都喜欢看到这样的语法特性: ; ; int total = x + y; 而不是用下面的语法来完成一样的事情: ...

  9. 博友的 编写高质量代码 改善java程序的151个建议

    编写高质量代码 改善java程序的151个建议 http://www.cnblogs.com/selene/category/876189.html

  10. 编写高质量代码改善C#程序的157个建议[1-3]

    原文:编写高质量代码改善C#程序的157个建议[1-3] 前言 本文主要来学习记录前三个建议. 建议1.正确操作字符串 建议2.使用默认转型方法 建议3.区别对待强制转换与as和is 其中有很多需要理 ...

随机推荐

  1. MyBatis的类型自定义映射

    背景 利用MyBatis将数据库的时间类型映射成Java8的时间类型,引申对不同类型的自定义映射 实现方法 1.实现MyBatis中TypeHandler接口 @MappedTypes(value = ...

  2. TypeScript设计模式之策略、模板方法

    看看用TypeScript怎样实现常见的设计模式,顺便复习一下. 学模式最重要的不是记UML,而是知道什么模式可以解决什么样的问题,在做项目时碰到问题可以想到用哪个模式可以解决,UML忘了可以查,思想 ...

  3. solr笔记之solr下载及安装

    在学习solr过程中,磕磕碰碰,遇到过许多问题,所以特写下笔记,以供需要的时候时常翻阅,也给能看到该博文的博友提供一个不全面的参考. 一.solr简介: Solr是一个独立的企业及搜索应用服务器,它对 ...

  4. mybatis基础,mybatis配置文件核心组件typeHandler元素

    无论是从预处理语句中设置一个值,还是从结果集里取出一个值,都会用类型处理器将获取的值以合适的方式转换成 Java 类型 可以重写类型处理器或创建你自己的类型处理器来处理不支持的或非标准的类型 实现 o ...

  5. python之实现批量远程执行命令(堡垒机)

    python远程批量执行 我并不是一个专业的开发,我一直在学习linux运维,对于python也是接触不久,所以代码写的并不是很规范简洁. 前段时间一个同学找我一起做一个自动化运维平台,我对pytho ...

  6. ajax 实现三级联动

    ajax 实现三级联动,相当于写了一个小插件,用的时候直接拿过来用就可以了,这里我用了数据库中的chinastates表, 数据库内容很多,三级联动里的地区名称都在里面,采用的是代号副代号的方式 比如 ...

  7. 剑指offer_(4)

    重建二叉树: 题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字. 例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍 ...

  8. [No0000C1]Excel 删除空白行和空白列VBA代码

    在exce中删除空行和空列的方法有很多,相对而言删除空行较为简单,只需进行筛选,将空白行筛选出来,删除即可,但要删除空列比较困难.因为你不能按列进行筛选删除.Excel中没有这个功能.当然你可以用另外 ...

  9. wp8数据存储--独立存储文件 【转】

    出自 : http://www.cnblogs.com/MyBeN/p/3339019.html 文章篇幅有点大,建议去源网看看 1.调用手机的独立存储 例如:IsolatedStorageFile ...

  10. TypeScript设计模式之组合、享元

    看看用TypeScript怎样实现常见的设计模式,顺便复习一下. 学模式最重要的不是记UML,而是知道什么模式可以解决什么样的问题,在做项目时碰到问题可以想到用哪个模式可以解决,UML忘了可以查,思想 ...