effecitve c++ 条款31-35

effective c++的下载地址http://download.csdn.net/detail/mlkiller/5335383

条款31: 千万不要返回局部对象的引用,也不要返回函数内部用new初始化的指针的引用

这个条款其实很好理解,我们一个一个来说。

第一不要返回局部对象的引用。

前面有些条款也讲了,如果返回引用的时候,确保这个引用指向的对象存在,和这一条完全一致。

我们分析一下这个过程:
1 返回局部对象的引用。
2 将局部对象的引用拷贝给外部函数的返回值。
3 释放局部对象。
4 这个时候引用的对象就是一个不可预知的东西。

看下面一个例子:
#include
using namespace std;

int &test()
{
	int i = 10;
	return i;
}

int main()
{

	int &i = test();
        cout<

我这里的输出结果是
10
2271928
一旦这个值被修改了,就会发生你意想不到的结果。
还有人会这么写int i = test();
这个时候,你怎么输出i,结果都是10.
我可以也疑惑,仔细想了想,其实是这么回事。
这里的i其实本身是个对象,不是引用,所以系统会把临时对象的值拷贝给它,这样后面的改变就没问题了。

但是,其实这样有两个问题,第一个,和函数本身的返回值有悖了,不如直接定义成返回int,第二,如果其他地方有人调用的时候使用了引用。还是会出问题。

第二,不要返回函数内部用new初始化的指针的引用

这个原因很简单,new的东西,必须对应一个delete。
你每次调用这个函数的时候必须提醒自己,后面要delete,一次两次还可以,多了话,肯定会忘记,同时别人根本没法使用你写的函数,光注释和说明,你要写好多,同时还要嘱咐别人“亲,注意delete哦”,相信没人敢录用你。

条款32: 尽可能地推迟变量的定义

这个条款的原因在于:
很多老的c语言的编译器,要求必须在开始的时候把所有你需要的变量都定义好。
这个代码是相当痛苦的,我遇到过在某通信软件中,开始你会先看到100行的变量。估计很多人看到这些变量就没有继续看下去的动力了。

基于这个历史原因,很多人还是习惯性的这样做。
但是c++就完全不必考虑这个问题了。
这样有两个好处:
1 代码易懂了很多,你定义一个变量,就去使用它,别人明显知道这个变量的意思。
    如果想前面的那样,你得来回翻页,以弄清楚这个变量什么时候第一次使用。来去推敲其中的含义。
2 c++中,这样做还可以高效。
   例如,对于类A 
     A a;
     a = b;
    明显比A a(b),效率低很多。

但是万事不是绝对的。
例如下面这个例子
for(int i= 0; i< 10;i++)
{
   A a;
   //使用a;
}
其实你在循环外面声明它会更好一点,
A a;
for (int i = 0; i<10;i++)
{
}
这样可以少了循环的析构和构造。

条款33: 明智地使用内联

内联函数这个其实比较复杂。
不要过分的去使用它, 因为他可能会带来一些潜在的问题。
但是,其实很多高版本的编译器,如果开了优化,会自动帮我生成一些内联函数。
所以,对于初学者,尽量避免使用。
如果通过测试,发现确实是某个函数频繁被调用,而且使用内联不会有不利影响的时候,可以考虑使用内联。

条款34: 将文件间的编译依赖性降至最低

如果你做过大型的c语言或者c++的程序,你会发现这个很重要。
编译一个代码需要,花费1个小时时间,那么你大量的时间都浪费在这个上面,你无时无刻的不痛恨自者构建代码的这些人。
其实这个的原因还是 头文件包含问题。

你包含这个头文件,一旦这个头文件被修改,所有和它相关的都要重新编译,所以编译器的增量编译也没有效果。
这个时候怎么办呢?
1 头文件中尽量少包含其他头文件。
2 尽量使用前置声明。
例如头文件test.h中

class string;

class A
{
     A(string a);
}
3 接口和实现分离
   接口里面可以使用类的指针,这样既可以隐藏细节,又可以保证编译的效率。

条款35: 使公有继承体现 "是一个" 的含义

c++本身是面向对象的程序,其实任何面向对象的程序都存在这个问题。
has  还是is.
如果是公有继承,那么就确保他们之间的关系“是一个。”

例如基类为形状。
继承类为圆形,三角形,平行四边形,矩阵,等等。

另外google的编程规范里面,要求最好只是用公有继承

你可能感兴趣的:(c/c++)