string类有可以调换方向的函数吗_深度剖析C++中的inline函数

8842e131d810336f4f56d039bbb6ed26.gif点蓝色字关注“CurryCoder”

微信公众号:CurryCoder的程序人生 

怕什么真理无穷,进一寸有一寸的欢喜

5a6e8206979b02b4bfffe055ab1630bc.png


1.inline函数的爱恨两难

内联函数比宏优点好很多,详细原因请参见尽量以const、enum、inline替换#define 。调用内联函数不需要承受函数调用所导致的额外内存开销,编译器最优化机制通常被设计用来浓缩那些“不含函数调用”的代码,所以当一个函数为内联函数时,或许编译器就因此有内联对其执行语境相关的最优化。“世界上没有免费的午餐”,内联函数背后的整体思想是:对一个函数的调用都以函数本体替换它,但这同时会增加你的目标码大小。在一个内存有限的机器上,过度使用内联函数会造成程序体积太大。即使用有虚拟内存,内联函数造成的代码膨胀也会导致额外的换页行为,降低指令高速缓存器的命中率。另一方面来说,如果内联函数的本体很小,编译器针对函数本体所产生的码可能比函数调用所产生的码更小。因此,将函数设置为inline,确实导致更小的目标码和较高的命中率。

2.inline函数卑微在线求助

inline只是对编译器的一个申请建议,不是强制命令,编译器可以选择对你的建议置之不理。这项申请可以隐式声明也可以显式声明,隐式声明是将函数定义在类的内部,如下所示:
class Person{
public:
    // ...
    int age() const {return mAge;}   // 隐式的内联函数
private:
    int mAge;
};
显式声明的方法则是在函数定义式前面加上关键字inline,如下面函数模板:
template<typename T>
inline const T& max(const T& a, const T& b){
    return a }
上述显式的声明方法中,值得注意的一点是:inline函数和函数模板通常都被定义于头文件中。但是,函数模板未必一定是内联的!!!inline函数通常一定被放置在头文件中,因为大多数构建环境在编译过程中进行内联动作,为了将一个函数调用替换为被调用函数的本体,编译器必须知道那个函数是啥样。内联动作在大多数C++程序中是编译期的行为。函数模板通常也被放置在头文件中,因为它一旦被使用,编译器为了将它具体化,需要知道它的样子。某些构建环境中,可以在连接期执行模板具体化,只不过编译期完成具体化的动作比较常见。3.inline函数与虚函数的爱恨纠缠

大部分编译器拒绝将太复杂(带有循环或递归、switch-case语句)的函数设置为inline,而且所有对虚函数的调用也都会使inline失效。这是因为虚函数是直到运行期才会确定调用哪个函数,而inline函数意味着执行前先把调用动作替换为被调用函数的本体,编译器工作在编译期。如果编译器都不知道该调用哪个函数,你也就明白了为啥虚函数不建议设置为inline。更多详情原因请看这里https://www.jianshu.com/p/84a8335444dd

4.糟糕的内联选择:构造函数与析构函数

不要被你的眼睛所欺骗,下面子类构造函数真的是空的吗???

class Base{
public:
    // ...
private:
    string bm1, bm2;
};

class Derived: public Base{
public:
    Derived(){}  // Derived构造函数真的是空的吗???
    // ...
private:
    string dm1, dm2, dm3;
};
当你使用new,动态创建的对象被其构造函数自动初始化;当你使用delete,对应的析构函数会被调用。当你创建一个对象时,基类及其每个成员变量都会被自动构造;当你销毁一个对象时,从子类开始执行析构动作。如果有个异常在对象构造期间抛出,该对象已构造好的那一部分会被自动销毁。你的程序内一定有某些代码让那些事情发生,这些代码即编译器在编译期间产生并安排在你代码中的某个地方。有时候,可能就存在于你的构造函数和析构函数中。上面表面上看起来空的Derived构造函数所产生的代码,如下所示:
Derived::Derived(){
    Base::Base();
    try{
        dm1.string();
    }
    catch(...){
        Base::~Base();
        throw;
    }

    try{
        dm2.string();
    }
    catch(...){
        dm1.string();
        Base::~Base();
        throw;
    }

     try{
        dm3.string();
    }
    catch(...){
        dm2.string();
        dm1.string();
        Base::~Base();
        throw;
    }
}
上面的代码并不能代表编译器真正产生的代码,因为真正的编译器会以更复杂的做法来处理异常。尽管如此,上面的代码已经能反映Derived的空白构造函数必须提供的行为。不论编译器在其内部所做的异常处理有多么复杂,Derived构造函数至少一定会陆续调用成员变量和基类两者的构造函数,而那些调用会影响编译器是否对此空白函数执行内联动作。最后,程序库的设计者必须知道:内联函数无法随着程序库的升级而升级。如果fun()是程序库中的一个内联函数,客户将fun()本体编进其程序中,一旦程序库设计者决定改变fun(),所有用到函数f()的客户端程序都必须重新编译。如果fun()是non-inline函数,一旦它有所修改客户端只需要重新连接即可。对程序开发而言,大部分调试器对内联函数都束手无策,因为你无法在一个并不存在的函数内部设置断点进行调试呢?哪些函数可以设置为inline呢?我的建议是:首先不要将任何函数声明为inline,或者将inline实施范围局限在那些一定可以成为inline的场合。5.总结(1) 将大多数inline行为限制在小型、被频繁调用的函数身上。这可以使以后的调试过程和二进制升级更容易,也可以使潜在的代码膨胀问题最小化。(2) 不要只是因为函数模板出现在头文件中,就将它们声明为inline。

觉得不错,请一键三连吧↓

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/353167.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

javafx基础教程_JavaFX教程–基础

javafx基础教程JavaFX似乎正在RIA领域获得发展。 有了正确的工具和开发支持&#xff0c;它肯定会成为下一个最佳技术“物”的代价。 我没有在这里写任何JavaFX评论&#xff0c;因为有很多技术评论可能对它进行了广泛的评论&#xff0c;但是&#xff0c;我将编写一个简单的教程&…

prepareStatement与Statement的区别

prepareStatement与Statement的区别 1:创建时的区别&#xff1a; Statement stmcon.createStatement(); PreparedStatement pstmcon.prepareStatement(sql); 执行的时候: stm.execute(sql); pstm.execute(); 2: pstm一旦绑定了SQL,此pstm就不能执行其他的S…

什么是Spring Boot以及为什么它是用于创建微服务的首选框架

为什么要使用Spring Boot创建微服务&#xff1f; Spring Boot是Java领域众所周知的首选框架&#xff0c;用于创建Micro Services。 使用Spring引导框架&#xff0c;可以非常轻松地创建Java应用程序。 现在&#xff0c;我们将看到Spring启动框架的一些功能&#xff0c;这使其成为…

嵌入式开发有年龄限制吗_什么?!考教资有年龄限制了?2020年我还能考吗?...

近几年教师资格证越来越火爆越来越多的人都想报考&#xff0c;却又担心年龄问题&#xff0c;那么考教师资格证有年龄限制吗&#xff1f;下面小编就给大家解答一下这个问题&#xff1a;报考教师资格证是没有年龄限制的&#xff0c;只有学历限制。报考幼师教师资格证的考生必须是…

Python3的bytes/str之别

Python 3最重要的新特性大概要算是对文本和二进制数据作了更为清晰的区分。文本总是Unicode&#xff0c;由str类型表示&#xff0c;二进制数据则由bytes类型表示。Python 3不会以任意隐式的方式混用str和bytes&#xff0c;正是这使得两者的区分特别清晰。你不能拼接字符串和字节…

jframe透明_使JFrame透明

jframe透明首先创建一个带有滑块的框架&#xff0c;该滑块将用于设置透明度量。 import javax.swing.JFrame; import javax.swing.JSlider;public class TransparentFrame extends JFrame {public TransparentFrame() {setTitle(Transparent Frame);setSize(400,400);setDefaul…

MyEclipse下Tomcat启动变慢的解决方法

项目忽然使用debug启动有时候会突然变得非常慢。不但启动慢&#xff0c;启动之后连打开项目标页面也很慢&#xff0c;是日常平凡的4&#xff0c;5倍。可以有下面的几种解决方法&#xff1a; 1、由于Tomcat是服务器,部署好的工程就会一直驻留到服务器里,每次启动都会把部署到服务…

Python关于Threading暂停恢复解决办法

我们都知道python中可以是threading模块实现多线程, 但是模块并没有提供暂停, 恢复和停止线程的方法, 一旦线程对象调用start方法后, 只能等到对应的方法函数运行完毕. 也就是说一旦start后, 线程就属于失控状态. 不过, 我们可以自己实现这些. 一般的方法就是循环地判断一个标志…

stm32l4 外部中断按键会卡死_STM32学习之路-按键中断测试(外部中断)

void RCC_Config(void){SystemInit(); //系统时钟初始化RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB| RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD| RCC_APB2Periph_GPIOE | RCC_APB2Periph_G…

NetBeans Java EE技巧9:从数据库创建JSF应用程序

您需要非常快速地创建数据库前端吗&#xff1f; NetBeans IDE允许人们以极少的编码就非常快速地为一组数据库表开发JSF应用程序前端。 现在&#xff0c;本教程既是老歌&#xff0c;又是老歌……对于那些不了解它的人来说&#xff0c;值得再次提及。 首先&#xff0c;创建您的应…

[模板]树链剖分

用途 我想把一个本来是线性的东西放到树上做&#xff0c;维护路径或者是子树的各种性质&#xff0c;那就用树剖呗 它可以套线段树、树状数组、ST表&#xff08;以及其他我不知道的&#xff09; 做法 我们考虑把树分成一条条链&#xff0c;然后对每条链维护我们的数据结构&#…

sql server 2005单独添加mdf文件

我把原来的数据库分离后&#xff0c;直接把日志文件给干掉了。原来在SQL 2000里经常这么干&#xff0c;只用一个mdf就附加了。没想到sql2005居然不行。我试验了一圈 终于找到一个成功的方法。转载&#xff0c;供后来者参考。SQL2005 如何在没有日志文件的情况下如何恢复MDF数据…

低压抽屉柜常见故障处理方法_低压配电设备常见故障分析,处理办法介绍

低压配电线路作为配电网络中主要的一部分&#xff0c;在其运行的过程中直接影响着人民的生命财产安全。配电线路是电力输送的终端&#xff0c;对于提高电力质量有着至关重要的作用。但由于配电线路走径的复杂性&#xff0c;人为因素和设备因素&#xff0c;都会给低压配电设备造…

关于C语言中的'\?'和%%

关于C语言中的\?和%% 一、引语 我们知道C/C中有四个非字母的字符需要用转义字符来表示&#xff1a;单引号 , 双引号 " , 反斜杆 \ 和问号 ? 显然这是因为它们本身有特殊的含义&#xff0c;所以要用转义字符来表示他们自己&#xff0c;单引号用来表示单个字符&#xff0…

mockito 使用_用Mockito回答

mockito 使用在编写单元测试时 &#xff0c;必须记住不要依赖于外部组件。 为了避免这种情况&#xff0c;我们使用了模拟框架&#xff0c;对我而言&#xff0c;最容易使用的是Mockito 。 在本文中&#xff0c;我们将看到在Mockito中使用的一种“高级”技术&#xff0c;可以使用…

jQuery常用操作

jQuery jQuery是一个轻量级的JS库&#xff0c;是一个被封装好的JS文件&#xff0c;提供了更为简便的元素操作方式&#xff0c;jQuery封装了DOM。 使用jQuery 引入jQuery文件 <scrtipt srcjquery-1.11.3.js> </script> 注意&#xff1a;引入必须放在其他jQuery操作之…

python tab和空格混用_我的 Python 编码规范

python 文件的组成为了便于描述&#xff0c;先上一个 demo#!/usr/bin/env python# -*- coding: utf-8 -*-"""通常这里是关于本文档的说明(docstring)&#xff0c;须以半角的句号、 问号或惊叹号结尾!本行之前应当空一行&#xff0c;继续完成关于本文档的说明如果…

Twitter创始人Jack Dorsey的每日必做和不做清单

Twitter创始人Jack Dorsey显然是这段时间以来技术界的中心人物&#xff0c;不仅发表了一系列的文章&#xff0c;而且一本反映Twitter早期岁月的书也即将出版。今天&#xff0c;他又在Y Combinator的Startup School上发表了讲话&#xff0c;不过在谈话中Dorsey回避了一切不必要及…