C++已经是一个多重泛型编程语言,同时支持过程形式、面向对象形式、函数形式、泛型形式和元编程形式的语言。
将C++视为一个由语言组成的联邦而非单一语言。在其某个次语言中,各种守则和通例都倾向简单、直观易懂并且容易记住。然而当你从一个次语言移到另一个次语言时,守则可能改变。
4个次语言:
· C :C++是以C为基础。区块、语句、预处理器、内置数据类型、数组和指针等都来自C。
· Object-Oriented C++ :classes。封装、继承、多态和virtual等,这一部分是面向对象设计之古典守则。
· Template C++ :C++的泛型编程部分。Template威力强大,它们带来崭新的编程范式,也就是所谓的TMP(模板元编程)。
· STL :STL是个template程序库。它对容器、算法、迭代器以及函数对象的规约有极佳的紧密配合和协调。
C++高效编程守则视状况而变化,取决于使用C++的哪一部分:
· 对内置类型(c-like)而言,pass-by-value通常比pass-by-reference高效。
图1 Source-code
图2 pass-by-value
图3 pass-by-reference
图4 pass-by-reference-to-const
可以看出,pass-by-reference(-to-const)相比于pass-by-value多了一步从寄存器中存放的地址取值的操作。
说明:
x86_64汇编:
传参方法:第一个参数是rdi,第二个是rsi,第三个是rdx,第四个是rcx,第五个是r8,第六个是r9,再往后就在rsp堆栈往上存储。返回值是rax。
· 对于Object-Oriebnted C++来说,由于用户自定义构造函数与析构函数的存在,pass-by-reference-to-const往往更加高效。运用template C++时更是如此。
图5 source code
图6 main
通过汇编代码可以看到pass-by-value将类对象拷贝了一份,作为参数传入的是这个拷贝产生的新的对象(调用了类默认的拷贝构造函数)。
· 对STL的迭代器和函数对象而言,旧式的C pass-by-value将再次适用,这是因为STL迭代器和函数对象都是在C指针之上塑造出来的。
图7 source code
图8 no_ref
图9 has_ref
从汇编代码可以看出来,对于指针类型入参,pass-by-reference相比于pass-by-value多了一次取值操作。