C++声明放置正确应用方式
C++编程语言既然被看做是C语言的升级版本,它必然会具有C语言中的很多功能。不过其中还是有很多比C语言更加优化的功能。比如C++声明的一些内容等。C++声明放置将会对性能产生显著影响。同样,对postfix和prefix运算符的选择也会影响性能。这一部分我们集中讨论四个问题:初始化v.s 赋值,在程序确实要使用的地方放置声明,构造函数的初始化列表,prefix v.s postfix运算符。
C++编程语言可以支持很多程序设计风格,能够在很大程度上帮助开发人员提高开发效率。初学者们可能还对C++中的声明有些不太明白,在这里我们将会为大家详细介绍一下C++声明放置的相关方法,方便大家理解。
(1) 请使用初始化而不是赋值
在C语言中只允许在一个函数体的开头进行变量的声明,然而C++声明放置可以出现在程序的任何位置。这样做的目的是希望把对象的声明拖延到确实要使用它的时候再进行。这样做可以有两个好处:
1. 确保了对象在它被使用前不会被程序的其他部分恶意修改。如果对象在开头就被声明然而却在20行以后才被使用的话,就不能做这样的保证。
2. 使我们有机会通过用初始化取代赋值来达到性能的提升,从前声明只能放在开头,然而往往开始的时候我们还没有获得我们想要的值,因此初始化所带来的好处就无法被应用。但是现在我们可以在我们获得了想要的值的时候直接进行初始化,从而省去了一步。
注意,或许对于基本类型来说,初始化和赋值之间可能不会有什么差异,但是对于用户定义的类型来说,二者就会带来显著的不同,因为赋值会多进行一次函数调用----operator =。因此当我们在赋值和初始化之间进行选择的话,初始化应该是我们的首选。
(2) C++声明放置在合适的位置
在一些场合,通过移动声明到合适的位置所带来的性能提升应该引起我们足够的重视。例如:
bool is_C_Needed(); void use() { C c1; if (is_C_Needed() == false) { return; //c1 was not needed } //use c1 here return; }
上面这段代码中对象c1即使在有可能不使用它的情况下也会被创建,这样我们就会为它付出不必要的花费,有可能你会说一个对象c1能浪费多少时间,但是如果是这种情况呢:C c1[1000];我想就不是说浪费就浪费了。但是我们可以通过移动声明c1的位置来改变这种情况:
void use() { if (is_C_Needed() == false) { return; //c1 was not needed } C c1; //moved from the block's beginning //use c1 here return; }
怎么样,程序的性能是不是已经得到很大的改善了呢?因此请仔细分析你的代码,C++声明放置所带来的好处是你难以想象的。
(3) 初始化列表
我们都知道,初始化列表一般是用来初始化const或者reference数据成员。但是由于他自身的性质,我们可以通过使用初始化列表来实现性能的提升。我们先来看一段程序:
class Person { private: C c_1; C c_2; public: Person(const C& c1, const C& c2 ): c_1(c1), c_2(c2) {} };
当然构造函数我们也可以这样写:
Person::Person(const C& c1, const C& c2) { c_1 = c1; c_2 = c2; }
那么究竟二者会带来什么样的性能差异呢,要想搞清楚这个问题,我们首先要搞清楚二者是如何执行的,先来看初始化列表:数据成员的声明操作都是在构造函数执行之前就完成了,在构造函数中往往完成的只是赋值操作,然而初始化列表直接是在数据成员声明的时候就进行了初始化,因此它只执行了一次copy constructor。再来看在构造函数中赋值的情况:首先,在构造函数执行前会通过default constructor创建数据成员,然后在构造函数中通过operator =进行赋值。因此它就比初始化列表多进行了一次函数调用。性能差异就出来了。但是请注意,如果你的数据成员都是基本类型的话,那么为了程序的可读性就不要使用初始化列表了,因为编译器对两者产生的汇编代码是相同的。
(4) postfix VS prefix 运算符