内联函数

[译]Google C++编程风格指南(一)

[亡魂溺海] 提交于 2019-12-10 05:37:42
背景 Google的开源项目大多使用C++开发。每一个C++程序员也都知道,C++具有很多强大的语言特性,但这种强大不可避免的导致它的复杂,这种复杂会使得代码更易于出现bug、难于阅读和维护。 本指南的目的是通过详细阐述在C++编码时要怎样写、不要怎样写来规避其复杂性。这些规则可在允许代码有效使用C++语言特性的同时使其易于管理。 风格,也被视为可读性,主要指称管理C++代码的习惯。使用术语风格有点用词不当,因为这些习惯远不止源代码文件格式这么简单。 使代码易于管理的方法之一是增强代码一致性,让别人可以读懂你的代码是很重要的,保持统一编程风格意味着可以轻松根据“模式匹配”规则推断各种符号的含义。创建通用的、必需的习惯用语和模式可以使代码更加容易理解,在某些情况下改变一些编程风格可能会是好的选择,但我们还是应该遵循一致性原则,尽量不这样去做。 本指南的另一个观点是C++特性的臃肿。C++是一门包含大量高级特性的巨型语言,某些情况下,我们会限制甚至禁止使用某些特性使代码简化,避免可能导致的各种问题,指南中列举了这类特性,并解释说为什么这些特性是被限制使用的。 由Google开发的开源项目将遵照本指南约定。 注意:本指南并非C++教程,我们假定读者已经对C++非常熟悉。 头文件 通常,每一个.cc文件(C++的源文件)都有一个对应的.h文件(头文件),也有一些例外

析构函数与virtual

别来无恙 提交于 2019-12-07 07:32:24
作为通常的原则,如果一个类定义了虚函数,那么它的析构函数就应当是virtual的。因为定义了虚函数则隐含着:这个类会被继承,并且会通过基类的指针指向子类对象,从而得到多态性。这个类可能会被继承,并且会通过基类的指针指向子类对象”,因此基类的析构函数是否为虚将决定子类的对象是否被析构。 #include <iostream.h> struct A { virtual ~A() {cout<<"~A()\n";} }; struct B: public A { ~B() {cout<<"~B()\n";} }; void main() { A* p = new B; delete p; } 如果 A 的析构函数不是virtual的,那么此时就不是先调用B的析构函数再调用A的析构函数。 输出为: ~A(); 如果 A 的析构函数为virtual,则先~B(),再~A(),输出为: ~B(); ~A(); 类如果会被派生的话,析构函数一般都应该定义为virtual的,主要不是防止内存泄露,而是为了正确的析构。如果是个封闭类(即不再被派生),就不要定义为virtual的。虚函数毕竟耗费较大的。 不用virtual 的几种情况: 作为非公有基类。仅作为 private base class 使用的 class 不需要使用虚拟析构函数。 不作为接口使用的基类。

c++内联函数

蹲街弑〆低调 提交于 2019-12-07 01:03:32
内联函数与普通函数的区别 传统函数的动作包括:压栈,跳转,返回,而内联函数直接在调用处执行函数体的命令,内联函数短小精悍,不允许包括条件判断,分支结构 来源: https://www.cnblogs.com/saintdingspage/p/12000311.html

C内联函数的内外链接的区别

微笑、不失礼 提交于 2019-12-06 05:43:57
C内联函数简介 inline提示编译器做可选优化,这就要求编译器能见到内联函数的定义(一般通过头文件引入编译单元),也就引入本节要讨论的焦点:内联函数外链接. 内联函数根据是否跟static修饰,分为内链接和外链接;顾名思义内链接仅在当前编译单元有效,若通过头文件引入其它编译单元,相当于一份同名拷贝,各自在不同编译单元有效,但这可能增大了二进制文件的体积(内联失败就带有多份静态函数的拷贝);外链接与之相反,它共享同一份代码. C内联函数使用 内联函数内链接 内联函数的内链接如: inline static void fn(void) {} 没有任何限制,使用简单,建议采用. 内联函数外链接 内联函数的外链接如: inline void fn(void) {} 则有诸多限制.如下: 一个非 static 的内联函数不能定义一个非 const 的函数局部 static 对象,并且不能使用文件作用域的 static 对象. static int x; inline void f(void) { static int n = 1; // 错误:非 const 的 static 对象在非 static 的 inline 函数中 int k = x; // 错误:非 static 的 inline 函数访问 static 变量 } 内联函数的外链接允许同名的外部函数,且在调用时行为是未指定的

引用和内联函数

我怕爱的太早我们不能终老 提交于 2019-12-05 04:45:33
一 内联函数   内联函数是C++为提高程序运行速度所做的一项改进。   编译过程的最终产品是可执行程序(由一组机器语言指令组成)。程序运行时,操作系统将这些指令载入到计算机内存中,因此每条指令都有特定的内存地址。   常规函数调用过程---程序跳到函数的地址,并在函数结束时返回。即,程序执行到函数调用指令时,将在函数调用后立即存储该指令的内存地址,并将函数参数复制到堆栈,跳到标记函数起点的内存单元,执行函数代码,返回值放入寄存器中,然后跳回到地址被保存的指令处(这与阅读文章时停下来看标注,并在阅读完标注后返回到之前阅读的地方类似)   内联函数是将相应的代码替换函数调用。优点是内联函数运行速度比常规函数稍快,缺点是占用更多内存。   要使用内联函数,需要:   (1)在函数声明前加上关键字inline   (2)在函数定义前加上关键字inline 注:内联函数不能递归   另:内联函数与宏的区别 内联函数参数传递方式与常规函数一样,宏是简单的文本替换来完成 例如: inline double square(double x) {return x*x; } #define SQUARE(X) X*X SQUARE(0.5) //->0.5*0.5 SQUARE(4.5+7.5) //4.5+7.5*4.5+7.5 SQUARE(c++) //c++*c++ 二 引用变量

c/c++——基本概念

跟風遠走 提交于 2019-12-05 01:01:16
内存 栈区和堆区的管理模式有所不同:栈区内存由系统分配和释放,不受程序员控制;堆区内存完全由程序员掌控,想分配多少就分配多少,想什么时候释放就什么时候释放,非常灵活。 栈(Stack)可以存放函数参数、局部变量、局部数组等作用范围在函数内部的数据,它的用途就是完成函数的调用。 栈区和堆区的内存在程序运行期间可以根据实际需求来分配和释放,不用在程序刚启动时就备足所有内存。这称为动态内存分配。 在栈上创建出来的对象都有一个名字,比如 stu,使用指针指向它不是必须的。但是通过 new 创建出来的对象就不一样了,它在堆上分配内存,没有名字,只能得到一个指向它的指针,所以必须使用一个指针变量来接收这个指针,否则以后再也无法找到这个对象了,更没有办法使用它。也就是说,使用 new 在堆上创建出来的对象是匿名的,没法直接使用,必须要用一个指针指向它,再借助指针来访问它的成员变量或成员函数。 栈内存是程序自动管理的,不能使用 delete 删除在栈上创建的对象;堆内存由程序员管理,对象使用完毕后可以通过 delete 删除。在实际开发中,new 和 delete 往往成对出现,以保证及时删除不再使用的对象,防止无用内存堆积。 有了对象指针后,可以通过箭头 -> 来访问对象的成员变量和成员函数,这和通过 结构体指针 来访问它的成员类似。 成员变量在堆区或栈区分配内存,成员函数在代码区分配内存

clang 编译器下的inline探索

橙三吉。 提交于 2019-12-04 03:59:29
clang 编译器下的inline探索 今天看到一篇文章说到inline内联函数的介绍文章,里面提到内联函数的作用以及适用场景,刚好最近看了clang编译器的一些资料,正好发了点时间探索下 这篇文章的介绍如下 内联函数 ( https://www.cnblogs.com/spock12345/p/11551147.html ) inline函数的作用:不是在调用时发生控制转移,而是在编译时将函数体嵌入在每一个调用处,适用于功能简单,规模较小又使用频繁的函数。 准备 代码 使用的示例代码如下,我这里把文件命名为 a.c #include <stdio.h> int inlinecalc(int a, int b, int fac); int inline_loopFunc(); void inline_recCallFunc(int count); inline int inline_loopFunc(){ //实现 int count = 1000; for (int i = 0; i < count; ++i) { printf("%d\n", i); } return 0; } inline void inline_recCallFunc(int count){ if (count > 0) { inline_recCallFunc(count-1); } printf("%d

C++虚函数(10) - 虚函数能否为inline?

守給你的承諾、 提交于 2019-12-03 22:05:08
虚函数用于实现运行时的多态,或者称为晚绑定或动态绑定。而内联函数用于提高效率。内联函数的原理是,在编译期间,对调用内联函数的地方的代码替换成函数代码。内联函数对于程序中需要频繁使用和调用的小函数非常有用。 默认地,类中定义的所有函数,除了虚函数之外,会隐式地或自动地当成内联函数(注意:内联只是对于编译器的一个请求,编译器可以自己决定是否进行内联). 无论何时,使用基类指针或引用来调用虚函数,它都不能为内联函数(因为调用发生在运行时)。但是,无论何时,使用类的对象(不是指针或引用)来调用时,可以当做是内联,因为编译器在编译时确切知道对象是哪个类的。 #include <iostream> using namespace std; class Base { public: virtual void who() { cout << "I am Base\n"; } }; class Derived: public Base { public: void who() { cout << "I am Derived\n"; } }; int main() { // 此处的虚函数who(),是通过类的具体对象来调用的,编译期间就能确定了,所以它可以是内联的。 Base b; b.who(); // 此处的虚函数是通过指针调用的,需要在运行时期间才能确定,所以不能为内联。 Base *ptr =

C++总结(1)keywords to the class

为君一笑 提交于 2019-12-03 15:38:26
目录 Chapter 1.关于类的关键字 1. class,struct与union 2.private,public与protected 3.friend 4.virtual 5.const 6.inline 7.template 8.delete与default 9.final与override 10.explicit 11.extern与static 12.constexpr Chapter 1.关于类的关键字 1. class,struct与union 1.1简述: ​ class是我们最为熟悉的C++类声明的关键字,便不再多提了,而C++的struct相比C中struct而言很不一样了,已经扩充了很多东西,而union是一种一种特殊的类,相比前两者就比较少用了,但也不排除有派得上用场的时候。 1.2 详解: struct与class ​ 刚从C转自C++时,大多数人总是仍把struct当作原来熟悉的包含各种数据的结构体,其实不然。士别三日,即更刮目相看。struct已经可以包含成员函数,可以继承,甚至可以多态,class能做到的,它基本上都可以做到。 ​ 那为啥还要class呢?那是因为它们二者还是有区别的,而且关键是它们的定位是不同的。 ​ 首先,struct与class最本质的区别是默认访问控制----struct是public的,class是private的。

C++——函数

大城市里の小女人 提交于 2019-12-03 12:10:47
C++基础函数 (一)函数的参数传递 在没有调用函数之前,函数的形参并没有占据实际的空间。 1、值传递 传入的仅仅只是一个值——就是把实参的值赋给形参。形参自己会在内存中开辟一个空间! 2、传引用 这种参数传递的方法就是给实参重新起了一个名字,实际上空间还是在原有的空间上对变量进行操作! 3、传地址 这种传参数的方式就是传一串地址,所以函数里面的一系列对参数进行的操作仍然是在原有的空间上进行操作。 (二)默认参数 1所有参数有默认值 带有部分默认值得参数 这个时候对默认参数值的参数必须写下后面!这个参数的默认值在声明的时候有了,那么在定义的时候就不要重复定义了,否则就会出错! #include <iostream> using namespace std; void m(int a, int b = 9); void m(int a, int b = 9)//重复定义的含有默认值的参数——编译报错! { int c; c=a + b; } void main() { int b = 2, c = 3; m(c); } 备注 : 关于函数默人参数值,在后面我们学习类的类型转换还会有接触的。 (三)内联函数 内联函数不是在调用时发生的控制转移,而是在编辑是将函数体嵌入在每一个函数调用处 .这样节省了参数传递,控制转移等开销! 关键字——inline 函数类型 函数名(参数列表){函数体