Effective C++之《实现》章节

条款30. 透彻了解inline的内外

此处注意,在C++98前,inline关键字多用于提示编译器在调用该函数的地方用函数本体替换之,减少调用的消耗。现代编译器几乎不再参考coder手动写的inline,而是通过编译器内部实现的统计方法自动inline,因此对比原文的条款,更应注重inline的其余用途.
此外:
模板函数和类内定义函数默认是inline的
函数指针call的函数以及虚函数不会被内联

.h文件中跨编译单元

  • inline关键字允许一个函数在多个编译单元中重复存在,因此可以写在头文件中。
  • inline关键字修饰的函数不保证一定会生成可链接的代码,因此必须写在头文件中,否则只能被当前编译单元使用,无法被其它编译单元调用。

如果在xxx.h文件中声明并定义了函数,如果该头文件被多个其他文件包含的话,必须使用inline关键字修饰,否则会报错multiple defined.
那么inline函数究竟有什么作用呢?inline函数要放在 .h 头文件里边,非inline函数要放进 .cpp 源文件中,这就是最主要的区别。(.cpp文件只被编译一次,.h文件会被多次编译)
例如,有函数:

//a.h
#ifndef A_H
#define A_H
namespace staticTest {
    inline int &getStaticValue() { // 此处不加inline的话,就会报错multiple defined
        static int a = 1;
        return a;
    }
}
#endif //A_H

// f1.cpp
#include "iostream"
#include "a.h"

int f1() {
    auto &v = staticTest::getStaticValue();
    std::cout << &v << std::endl;
    return ++v;
}
/
// f2.cpp
#include "iostream"
#include "a.h"

int f2() {
    auto &v = staticTest::getStaticValue();
    std::cout << &v << std::endl;
    return ++v;
}
/
// main.cpp
#include <iostream>
#include "a.h"

using namespace std;

int f1();

int f2();

int main() {
    int v1 = f1();
    int v2 = f2();
    cout << v1 << " " << v2 << " " << v1 + v2 << endl; // 2 3 5
}

C++17:作用于变量

可以在类内初始化static变量

//a.h
#ifndef A_H
#define A_H
struct Test{
    inline static int value = 1;
};
#endif //A_H

// f1.cpp
#include "iostream"
#include "a.h"

int f1() {
    auto v = Test::value;
    std::cout << v << " " << &v << std::endl;
}
/
// f2.cpp
#include "iostream"
#include "a.h"

int f2() {
    auto v = Test::value;
    std::cout << v << " " << &v << std::endl;
}
/
// main.cpp
#include <iostream>
#include "a.h"

using namespace std;

int f1();

int f2();

int main() {
    f1();
    f2();
    //	1 0xf5a43ff60c
	//	1 0xf5a43ff60c
}

作用于namespace

可以在外部命名空间直接使用内部内容

// a.h
namespace Test {
    int f1() {
        std::cout << "f1" << std::endl;
    }

    inline namespace Test_c1 {
        int f1(int i) {
            std::cout << "child_f1 " << i << std::endl;
        }
    }
}
// main.cpp
int main() {
    Test::f1(1); // 如果没有使用inline修饰namespace的话,只能Test::Test_c1::f1(1);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值