没有.cpp文件没有内联函数的c++类?

标签 c++ templates c++11 linker

我已经问过类似的问题,但这个有点不同

我不想为每个简单的 c++ 类编写一个 .cpp 文件。

当我在单个 .hpp 文件中编写类定义和声明时,链接器提示成员函数的多个定义,这些成员函数未在类主体内实现或使用内联键盘定义。

例如,这会起作用,但成员函数将变为内联:

// log.hpp file
#pragma once
#include<iostream>

class log {
  private:
    static int m_cnt = 0;
  public:
    void log();
};

inline void log::log() {
    std::cout << ++m_cnt << std::endl;
}

所以我使用模板来摆脱链接器的提示,并希望成员函数不会变成内联的(是吗?):

// log.hpp file
#pragma once
#include<iostream>

template<typename T>
class log_t {
  private:
    static int m_cnt = 0;
  public:
    void log();
};

template<typename T>
void log_t<T>::log() {
    std::cout << ++m_cnt << std::endl;
}

// some random type (int)
typedef log_t<int> log;

然后我可以在多个 .cpp 文件中简单地使用日志类,而不会出现链接器投诉。

即使我使用这种方法,成员函数也会变成内联的吗?

最佳答案

虽然将所有内容放在一个 .h 中通常是不好的做法文件,有些情况下这样做更方便。尤其是在定义小类时,以及在代码可以快速更改的原型(prototype)设计阶段。

我真的不建议使用模板来解决链接问题,因为它会减慢编译速度并导致混淆:这就像创建一个接受参数的函数,但你除了该参数始终具有相同的值。无论如何,输入 inline短于 template<typename T> ;)

所以你要么必须在类主体中定义你的方法,要么用 inline 注释它们如果定义在 body 之外。这是等价的,因为 C++ 会自动添加 inline类主体中定义的方法。

您关心的似乎是生成的代码,您可能想知道二进制文件是否会增长太多。但一切都很酷,因为不管 inline注释,编译器查看每个函数调用并决定是内联它还是生成调用。这意味着同一个函数有时可能会被内联(如果在循环中调用)有时会被调用。

不同的编译器有不同的启发式,但是 inline关键字对编译器的决定没有特别大的影响。您可以使用类似 __forceinline 的东西或 __attribute__((always_inline))更强烈地要求内联一个函数,但即使这样也不能保证所有对该函数的调用都会被内联。相反,您可能对 __attribute__(noinline) for gcc 感兴趣这将(几乎)永远不会内联调用:

inline __attribute__(noinline) void log::log() // gcc
{
    std::cout << ++m_cnt << std::endl;
}

如果你真的想知道你的代码中发生了什么,你可以使用 -Winline什么时候看inline函数不是内联的。

您还可以使用 -Os-Oz更改内部编译器阈值的优化级别,以减少内联。

您可能感兴趣的相关问题:herehere .

关于没有.cpp文件没有内联函数的c++类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22502136/

相关文章:

c++ - 何时在 C++ 中使用指针到指针?

c++ - 描述符转换问题

c++ - 有没有办法找到任意类类型的直接基类(如果有的话)?

jquery - 2012 年推荐的 jQuery 模板?

c++ - 如何针对程序相似的不同数据类型专门化模板函数?

c++ - 通过基类完美转发

c++ - 流式传输和循环 MS ADPCM (WAVE_FORMAT_ADPCM)

c++ - 在 C++ 中没有效果的语句有什么用?

c++ - protected 变量命名和标准

c++ - unique_ptr 参数。错误 C2664