宁可以编译器替换预处理器

define 不被视为语言的一部分,因此也就有可能在预处理阶段被优化掉,导致相关变量出现错误。

#define ASPECT_RATIO 1.63
//可以尝试将其替换为
const double AspectRatio=1.63

这里注意一下大写名称常用于宏,因此,转写时候将相关名称进行了相应的替换

1.定义常量的指针constant pointers 由于定义式通常被放在头文件内,因此有必要将指针声明为const

若要在头文件内定义 一个常量

char * based字符串

必须要写两次

const char *const authorName="ScottMeyers"

或者在C++中将其写成如下格式

const std::string authorName("ScottMeyers");

2.class 专属常量,为了将常量的作用域(scope)限制于class内,你必须让他成为class的一个成员member;而为了确保此常量至多只有一份实体,它就必须有必要成为static成员

class Sem
{
private:
static const int isnum=5;//这里是常量式的声明
int scores[isnum];
public:
void std_print()
{
std::cout<<isnum;
std::cout<<" ";
for(auto s:scores)
{
std::cout<<s<<" ";
}
std::cout<<std::endl;
}
};
private:
static const int isnum=5;//这里是常量式的声明
int scores[isnum];
private:
static const int isnum;//将声明放在头文件里面
const double Sem::isnum=5;//将实现放在文件中
private:
enum {isnum=5};//the enum hack补偿做法,即一个属于枚举类型的数可权充int 被使用
int scores[isnum];

关于宏与内联函数:尽量以内联的模板函数代替宏(类似于实现函数功能的宏)

#include <iostream>
#define CALL_WITH_MAX(a, b) ((a) > (b) ? (a) : (b))
int main()
{
int a = 5, b = 0;
CALL_WITH_MAX(++a, b);//这里的++会执行2次
std::cout << a << " " << b << std::endl;
CALL_WITH_MAX(++a, b + 10);//这里的++就执行一次
std::cout << a << " " << b << std::endl;
}

原因:第一次执行的宏从简单替换开始返回到a后再执行一次++

而第二次执行的宏因为没有返回到a,这次返回到的是b所以不会有第二次++

相反的若要替换成功能相同的内联函数就不会出现这样的问题

template <typename T>
inline T CallWithMax(const T&a,const T&b)
{
return (a>b?a:b);
}

如此而言,对于单纯的常量,最好用const对象或者enums替换掉#defines

对于形似函数的宏可以用inline函数替换掉

EffectiveC++的更多相关文章

  1. [EffectiveC++]item04:Make sure the objects are initialized before they're used

    28 页 C++规定,对象的成员变量的初始化动作发生在进入构造函数本体之前. 构造函数的一个较佳的写法是,使用所谓的member initialization list替换赋值动作. 29页 但请立下 ...

  2. [EffectiveC++]item34:区分接口继承和实现继承

    [EffectiveC++]item34:区分接口继承和实现继承

  3. effectiveC++ 内存管理 学习笔记

    1.尽量使用初始化列表而不要再构造函数里赋值,初始化顺序和声明的顺序一致,一些类型如const,引用等,必须使用初始化.对于非内部数据类型成员对象应当采用初始化表,以获取更高的效率.example:B ...

  4. effectivec++条款18,让接口容易被正确使用,不宜被吴勇

    test* create_test(); shared_ptr<test> create_test();//下面的接口比上面的接口要好 auto_ptr<test> creat ...

  5. EffectiveC#18--用IComparable和IComparer实现对象的顺序关系

    1..Net框架提供了接口来描述对象的顺序关系:IComparable 和IComparer. 2.IComparable 为类定义了自然顺序,实现IComparer接口的类可以描述其它可选的顺序 3 ...

  6. EffectiveC#03--用委托表示回调,用事件定义对外接口

    1.回调的场景:我给了儿子一个任务且他可以报告状态来(重复的)打断我.而我在等待他完成任务的每一个部份时不用阻塞我自己的进程.他可以在有重要(或者事件)状态报告时,可以定时的打断我,或者向我询求帮助 ...

  7. EffectiveC#02--仅在对基类进行强制更新时才使用new修饰符

    1.建议避免使用new修饰符来重新定义非虚函数. 非虚方法是静态绑定的,不管哪里的代码也不管在哪里引用, 它总是严格的调用类中所定义的函数.并不会在运行时在 派生类中查找不同的版本. 2.何时使用ne ...

  8. EffectiveC#01--避免返回内部类对象的引用

    此篇是对00中第3点的再一次阐述. 1.如果一个属性返回一个引用类型,那么调用者就可以访问这个对象的公共成员,也包括修改这些属性的状态. public class MyBusinessObject { ...

  9. EffectiveC#00--选择定义和实现接口,而不是继承

    1.继承就是说它是某物(is a的关系),针对相关类,而接口是说它有某个功能(behaves like.)可以是不相关的 基类是描述对象是什么,接口描述对象有某种行为. 2.不能在接口里提供任何成员的 ...

  10. EffectiveC#17--装箱和拆箱的最小化

    1.如下这段代码会经历装箱和拆箱.例如25会先装箱成object后传递给writeline方法(一次拷贝),在方法内部又 经历拆箱成int(第二次拷贝)后然后调用tostring(). Console ...

随机推荐

  1. 删除git中无用的大文件

    推荐阅读:为什么你的 Git 仓库变得如此臃肿 有时候我们不小心提交了一些大文件上去,后来删除了,但是已经于事无补了,整个git的提及已经蹭蹭上去了. 这个时候怎么办呢? 1. 查看有哪些大文件(to ...

  2. 前端逼死强迫症系列之javascript

    JavaScript 和Python.C#.Java.Ruby一样,都是一门独立的编程语言. 像python.C.Java等都需要解释器,学习它们的语法.而浏览器本身就是javascript的解释器. ...

  3. 二十、网络ifconfig 、ip 、netstat、ss之二

    ip 网络层协议 ip地址 点分十进制分为4段,范围 0-255 ip分类 A 占据1段,最左侧一段第一位固定为0 0 000 0000 - 0 111 1111  0 - 127:其中0为网络,12 ...

  4. easyui的combobox模糊搜索

    <tr> <th>测试名称:</th> <td> <select data-options="" class="ea ...

  5. 【locust】使用locust + boomer实现对接口的压测

    背景 很早之前,考虑单机执行能力,使用locust做过公司短信网关的压测工作,后来发现了一个golang版本的locust,性能是python版本的5到10倍以上,但是一直没有机会使用. 最近公司想做 ...

  6. 一个简单的puppeteer爬虫

    const puppeteer = require("puppeteer"); const path = require('path'); const pathToExtensio ...

  7. (main)贝叶斯统计 | 贝叶斯定理 | 贝叶斯推断 | 贝叶斯线性回归 | Bayes' Theorem

    2019年08月31日更新 看了一篇发在NM上的文章才又明白了贝叶斯方法的重要性和普适性,结合目前最火的DL,会有意想不到的结果. 目前一些最直觉性的理解: 概率的核心就是可能性空间一定,三体世界不会 ...

  8. kotlin 代码格式

    与java 不同,代码顺序影响编译过程. { var a:Int = 1; init(){ a++; } //var a:Int = 1;  写在 init 之后不可用. }

  9. PHP学习之图像处理-水印类

    <?php $image = new Image(); $image->water('./upload/up_5cf0caca0565b.png','./upload/up_5cf0cb3 ...

  10. context_processor 上下文处理器

    context_processor 上下文处理器 博客里面有三个地方用到了标签云:主页面,分类页面,博客详情页面,于是有了下面一段代码 # 主页面 @main.route("/") ...