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

C++ c++;没有.cpp文件但没有内联函数的类?,c++,templates,c++11,linker,C++,Templates,C++11,Linker,我已经问了一个类似的问题,但这个问题有点不同 < >我不想为每个简单的C++类编写.cpp文件。 当我在一个.hpp文件中编写一个类定义和声明时,链接器会抱怨成员函数的多个定义没有在类的主体中实现,也没有使用内联键盘定义 例如,这将起作用,但成员函数将成为内联函数: // log.hpp file #pragma once #include<iostream> class log { private: static int m_cnt = 0; public:

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


< >我不想为每个简单的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文件
#布拉格语一次
#包括
类日志{
私人:
静态int m_cnt=0;
公众:
无效日志();
};
内联void log::log(){

std::cout一般来说,将每个实现都放在头文件中是一个坏主意,因为这会导致大型项目的编译时间非常长。使用模板来避免这种情况也不是一个好主意,因为它不会改变这一事实


inline
只是对编译器的一个提示;它可能会忽略它并内联您的模板代码或不内联。简言之:您的问题的答案并不重要。标准/最好的方法是使用.cpp文件来实现,即使您想避免它。

而将所有内容放在一个
.h中通常是不好的做法文件,在某些情况下这样做更方便。特别是在定义小类时,以及在原型阶段,代码可以快速更改

我真的不建议使用模板来解决链接问题,因为它可能会减慢编译速度并导致混乱:这就像创建一个函数,当您希望参数始终具有相同的值时,使用参数。无论如何,键入
inline
template
;)短)

这样,你就必须在类体中定义方法,或者如果在正文中定义,则用<代码>内联< /代码>注释。这是等价的,因为C++自动将<代码>内联< /代码>添加到类体中定义的方法。

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

不同的编译器有不同的启发式方法,但
inline
关键字对编译器的决策没有特别大的影响。您可以使用
\uuuuuforceinline
\uuuuuu属性(总是inline))之类的方法
使ask更强烈地内联函数,但即使如此,也不能保证所有函数调用都将内联。相反,您可能会对(几乎)永远不会内联调用的函数感兴趣:

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

STD::“我不想为每个简单的C++类编写.CPP文件。”为什么?如果你不想用,也不要使用内联……这并不意味着编译器不会做它,如果它认为它会生成更好的代码。不,你可以在多个文件中定义,但是函数体应该留在.CPP(对于内联函数来说它不能)。这是很有见解的,但IMO没有。它简单,或者不重要,短或不…h是定义和.CPP实现。你必须为模板或内联函数设置.h实现,但是对于其他所有东西都保持这个意思。@阿明认为像C开发人员在编写C++代码时可能不帮助。
inline
不是一个指令,只是一个提示/注释。编译器自己决定内联什么。有时,同一个函数可以在某些调用站点内联,而不能在其他调用站点内联,只需让编译器完成它的工作。你可以使用
-Os
进行编译,以减少内联。我只想知道这是否可行?如果我需要我们的话e内联键盘编译器可能内联函数,也可能不内联函数?“一般来说,将每个实现都包含在头文件中是一个坏主意”--告诉
boost
库。Jeffrey,他们正在模板化他们的内容,因此没有其他选择;-)(当然有,但它涉及到将头拆分为接口头和实现头,并在.cpp文件中实例化每个常用的模板参数组合…)amin,这是可能的。但是
inline
只是对编译器的一个提示。它可以内联您没有声明为
inline
的内容,或者生成一个单独的函数,尽管声明了
inline
inline __attribute__(noinline) void log::log() // gcc
{
    std::cout << ++m_cnt << std::endl;
}