//条款01:视C++为一个语言联邦
// 1:C++主要包含的语言为:
// A:C。说到底C++仍然以C为基础。区块(blocks)、语句、预处理器、内置数据类型、数组、指针等均来自于C。许多时候C++对于问题的解决不过是较高级的C解法。当以C++内的C成分
// 工作的时候,高效编程守则映照出C语言的局限:没有模板,没有异常,没有重载等。
// B:Object-Oriented C++。这部分也就是C with Class所述求的:class(包括构造函数和析构函数),封装,继承,多态,虚函数(动态绑定)等。这一部分是面向对象设计之古典守则在C++上最直接实施。
// C:Template C++。这是C++的泛型编程。
// D:STL。它对容器、迭代器、算法以及函数对象的规约有极佳的紧密配合与协调。
// 2.C++并不是一个带有一组守则的一体语言,它是四个次语言组成的,每个次语言都有自己的规约。 //条款02:尽量以const enum inline替换#define
// 1.const 与 #define
// A:#define CVALUE 5 上述语句并没有使得CVALUE被编译器看见,有可能就没有进入记号表内。于是当使用此常量导致的编译错误可能会提及5而不提及CVALUE,这将使问题难以追踪。
// 并且由于预处理器盲目地将宏名称替换为其对应的东西而导致代码产生冗余。而下列语句 const int CValue = 5; 则不会出现上述的问题。
// B:当在类中使用类的专属常量的时候可以使用const来实现,不能用#define实现,因为#define不注重作用域,一旦宏被定义,它就在其后的编译过程中有效(除非在某处被#undef)
class CTest
{
public:
const static int CSValue0 = 1; //类的专属常量的声明。在vs2010中不需要再类外进行声明就可以直接使用此变量
const static int CSValue1; //类的专属常量的声明,但是没有进行定义,在使用前必须进行定义,否则会出错
};
const static int CSValue0; //正确,类的专属常量的定义。
const int CTest::CSValue1 = 1; //类的专属常量的定义。
// 2.enum 和 #define
// A:在class编译期间需要一个class常量值也可以使用类内枚举。对一个const变量取地址是合法的,对一个枚举值取地址是非法的,而取一个#define的地址通常也是不合法的
// B:优秀的编译器不会为整形const对象设定另外的存储空间(除非创建一个指针或引用指向该对象),不过不够优秀的编译器(包括vs2010)却可能为const对象创建存储空间。但是enum和#define都绝不会导致非必要的内存分配
class CTest
{
public:
CTest() : CCV(10) {} #define CDV 10
enum{CEV};
const int CCV;
};
int size = sizeof(CTest); //vs2010下, size值为4
// 3.inline 和 #define
// A:宏看起来像函数,但是不会招致函数调用带来的额外开销。比如:
#define Max(a, b) ((a) > (b) ? (a) : (b)) //首先这里必须为每个变量加上括号
int a = 10, b = 10;
int value0 = Max(++a, b); //value0 = 12 其中a被累加2次
int value1 = Max(++a, b + 10); //value1 = 20 其中a被累加1次
// B:由上述代码可知,a被累加的次数居然取决于被比较的对象,这就十分荒谬了。而使用inline则可以完美解决上述问题
template<typename T>
inline T Fun(const T &a, const T &b)
{
return a > b ? a : b;
}
// 4.有了const enum inline 我们对预处理器(特别是#define)的需求降低了,但是并非完全消除。#include仍然是必需品。#ifdef/#ifndef也扮演控制编译的重要角色。 //条款03:尽可能的使用const
// 1.令函数返回一个常量值,往往可以降低因客户错误而造成的意外,而不至于放弃安全性和高效性。比如:
const operator *(const CTest &Test1, const CTest &Test2); //可以有效防止比如: (Test0 * Test1) = Test2;
// 2.将不需要被改变的量声明为const的,有助于在判断表达式中意外将==写成=造成的错误,以及防止其被意外修改。
// 3.将const作用于成员函数的目的是为了确认该成员函数可作用于const对象上。
// 4.区分顶层const和底层const,顶层const表示const所修饰的变量本身是常量,而底层const一般作用于指针,表示指针所指对象是常量。
// 5.将成员变量声明为mutable的,则即使在常量成员函数中也能修改这个变量的值。
// 6.当成员函数的常量版本和其非常量版本有着实质的等价实现的时候,最好是在其非常量版本中调用常量的版本,反之则违背了常量成员函数不修改其成员的规则,可能会导致逻辑错误。 //条款04:确定对象被使用前已经被初始化
// 1.读取未初始化的值会导致不明确的行为。
// 2.C++对于定义在不同cpp中的全局变量的初始化顺序没有进行规定,所以一个cpp中的全局变量不要依靠另一个cpp中的全局变量进行初始化,否则可能会产生bug
// 3.对于第二点的解决方法是:将全局变量局部static化。比如:
int& fun()
{
static int value = 10;
return value;
}//将每个全局变量搬到自己的专属函数中,然后由用户调用这些函数以获取其需要的变量。C++保证,函数内的局部static变量会在该函数调用期间,首次遇上该对象的定义式时被初始化(当此函数没有被调用的时候就省去了此变量的构造和析构)。
// 4.构造函数最好使用成员初始化列表进行对其成员的初始化。

  

Effective C++ 1.让自己习惯C++的更多相关文章

  1. 《Effective C++》让自己习惯C++:条款1-条款4

    条款1:视C++为一个语言联邦 可以将C++分为4个层次: 1.C:C++实在C语言的基础上发展而来的. 2:Object-Oriented C++:C++面向对象. 3:Template C++:C ...

  2. 【Effective C++】让自己习惯C++

    条款01:视C++为一个语言联绑 C++的四个语言层次: C:C++是以C为基础的.基本数据类型.语句.预处理器.数组.指针等统统来自C. Oject-Oriented C++:面向对象这一特性包含了 ...

  3. Effective C++: 01让自己习惯C++

    01:视C++为一个语言联邦 1:今天的C++已经是个多重范型编程语言(multiparadigm programming language),一个同时支持过程形式(procedural).面向对象形 ...

  4. 深入浅出c++之---this指针

    前言:C语言中的数组指针和指针数组 数组指针,是指向数组的指针的缩写:指针数组,是存放指针的数组的缩写.其实很多时候,往往因为简写和缩写带给我们很多困惑.我曾想过不用简称去学习,但在很多时候,我们查询 ...

  5. 我要好offer之 C++大总结

    0. Google C++编程规范 英文版:http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml 中文版:http://zh-g ...

  6. [.NET] 《Effective C#》快速笔记(一)- C# 语言习惯

    <Effective C#>快速笔记(一)- C# 语言习惯 目录 一.使用属性而不是可访问的数据成员 二.使用运行时常量(readonly)而不是编译时常量(const) 三.推荐使用 ...

  7. 《Effective C#》快速笔记(一)- C# 语言习惯

    目录 一.使用属性而不是可访问的数据成员 二.使用运行时常量(readonly)而不是编译时常量(const) 三.推荐使用 is 或 as 操作符而不是强制类型转换 四.使用 Conditional ...

  8. 《Effective C++》第1章 让自己习惯C++-读书笔记

    章节回顾: <Effective C++>第1章 让自己习惯C++-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(1)-读书笔记 <Effecti ...

  9. Effective C++(第三版)笔记 ---- 第一部分让自己习惯C++

    内容从侯捷译版的<Effective C++>(第三版)摘录 条款一 C++作为一个多种范式融合的语言,可以看成是语言的联邦,它包含了一下四种主要的次语言: C.C++以C为基础,很多时候 ...

随机推荐

  1. P1434 滑雪

    水题,记忆化搜索,队列bfs均可 我们定义f[i][j]为到(i, j)的最长路径.然后就不难得出状态转移方程,然后使用无脑dfs,或者有脑递推都是可以的. #include <bits/std ...

  2. 【转】get a mysterious problem,when i use HttpWebRequest in unity c# script

    in script,i use HttpWebRequest to get service from network.but it comes a mysterious problem. the so ...

  3. 读书笔记——《图解TCP/IP》(4/4)

    经典摘抄 第八章 应用层协议概要 1.应用协议是为了实现某种应用而设计和创造的协议. 2.TCP/IP的应用层包含了管理通信连接的会话层功能.转换数据格式的表示层功能,还包括与对端主机交互的应用层功能 ...

  4. Qt中单例模式的实现(4种方法)

    最简单的写法: 12345 static MyClass* MyClass::Instance(){ static MyClass inst; return &inst;} 过去很长一段时间一 ...

  5. 【Java 基础篇】【第四课】初识类

    看看Java中如何定义一个类,然后用来调用的,这个比较简单,直接看代码吧. 我发现的类和C++不一样的地方: 1.Java中类定义大括号后没有分号: 2.好像没有 public.private等关键字 ...

  6. php---将数组转化为数组对象

    例子:array(1){ [0]=>array( 'id'=>111, 'name'=>'aaaa' ) } 由上面的例子转化成下面对象,怎么转化?急急 急 谢谢array(1) { ...

  7. php---实现保留小数点后两位

    PHP 中的 round() 函数可以实现 round() 函数对浮点数进行四舍五入. round(x,prec) 参数说明x 可选.规定要舍入的数字.prec 可选.规定小数点后的位数. 返回将 x ...

  8. Internal Server Error500

    开启#LoadModule rewrite_module modules/mod_rewrite.so

  9. django 笔记

    最近开始接触django,一些基本的操作记录于此. 参考链接: http://www.ziqiangxuetang.com/django/django-tutorial.html django安装 s ...

  10. 3. 如何封装查询条件与查询结果到map中

    public Map<String, Object> queryOrderStatus(String orderNo) { // 查询到的结果与查询的条件一一对应,封装到map中! Str ...