c++编程习惯一(尽量用const,enum,inline替换宏)

在c语言中,我们经常用到宏定义,但是我们使用时并没有考虑太多的因素。

其实宏定义有时候不能被视为程序的一部分,当在使用 #define PI 3.14 时,其实编译器是看不到的,宏定义只会被预处理器看到,

什么意思呢,在编译器开始处理源码之前,宏可能就已经被预处理器移走了,所以这就话可以更改为“宁可使用编译器取代预处理器”;

为什么是这样的呢,比如你定义的PI在程序运行时出了问题,这是错误提示可能会让你困惑,因为编译器没有获得PI记号,也许错误提到的是3.14,也就是说,你无法找到错误位置,再或者,你用的是别人写的头文件,那这时候,你就对这个3.14更没有概念了,于是就会因为追踪它浪费很多时间。

那么怎么解决这个问题呢,我们可以使用  const double PI = 3.14;这样做就没问题了,而且,这样的话,PI在内存中也只有一份,不会像宏替换那样出现很多份,节省内存。

 

在使用const时有两种特殊情况,一种是定义常量指针,因为我们在编写程序时,一般会把常量值放在头文件中,便于共享,因此要把指针声明为常量,而不是其内容,例如: const char * const name=“jack”; 这里第一个const修饰的是指针内容,第二个是指针的值,所以这个时候,指针的内容与值都不可以被改变。

在c++中使用string会更好些:const std::string name("hehe");

第二种值得注意的是:可以用const将常量限制在一个class内,这时需要将常量设置为类的私有成员而且设置成静态成员,这样确保了常量成员只有一份为所有类对象所共享;

class Student
{
  //常量声明
  static  const int num = 5;
  //常量使用  
  int scores[num];   
};

需要注意我们这里是声明而非定义,一般而言,我们是必须为使用的东西提供定义的,比如一个变量或者一个函数,但是class专属常量又是static,我们只要不取地址,可以声明不定义,但是如果取地址的话,就必须提供定义,这样:const int Student::num;

记住定义式要放在实现文件而不是头文件中。因为class常量在声明时已经获得了初始值,所以不能再设置初值。

 

宏定义是无法创建一个class专属常量的,因为它不重视作用域,他也不能被封装。

 

如果是在c语言中,我们想要宏定义函数,我们似乎除了使用普通函数没有别的方法去取代,但是在c++中,我们可以使用内联函数去取代宏。

用a,b中的较大值去调用函数f;

#define Call_max(a,b) f((a)>(b))?(a):(b))

我什么也不说的话,这种东西写出来也会让人痛苦不堪,宏函数有太多的弊端,代码冗长不说,还要给所有的实参加上小括号,即便加上了小括号也会出现一些尴尬的情况,这里我要吐槽一下,宏被作为很多人炫耀的手段,用来当作考察别人的手段,我其实并不这么认为,优秀的程序是不应该出现这些模棱两可的东西,编译器的版本不应该成为一种炫耀手段,这仅是我的个人观点,不喜勿喷。

在c++中,我们可以使用安全的内联函数来替代宏

template<typename T>
inline void Callmax(const T& a,const T& b)
{
    f(a>b?a:b);
}

由于不知道T是什么所以才用了模板,这样可以避免很多尴尬的情况,而且这是一个真正的函数,它遵守普通函数的作用域和访问规则,例如完全可以在类中写出private inline函数,而宏是做不到的。

总结:

有了const ,enum,inline 我们不在像c语言那样需要预处理器,降低了对预处理器的需求,但是预处理器还是十分有用,很多预处理指令使我们所必需的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值