【发布时间】:2014-03-19 09:59:19
【问题描述】:
我已经问过一个类似的问题,但这个问题有点不同
我不想为每个简单的 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 文件中使用日志类而不会引起链接器投诉。
即使我使用这种方法,成员函数也会内联吗?
【问题讨论】:
-
"我不想为每个简单的 c++ 类编写一个 .cpp 文件。"为什么?如果您不想使用 inline,无论如何都不要使用...这并不意味着编译器不会这样做,如果它认为它会生成更好的代码。
-
不,您可以在多个文件中包含定义,但函数体应保留在 .cpp 中(对于内联函数,它不能)。这是非常基于意见的,但 IMO 没有。简单与否,简短与否都没有关系。 .H 用于定义,.CPP 用于实现。对于模板或内联函数,您必须将实现放在 .H 中,但对于其他所有内容,请保留此区别。
-
@amin 在编写 C++ 代码时,像 C# 开发人员一样思考可能无济于事。
-
inline不是指令,只是提示/注释。编译器自己决定内联什么。有时,相同的函数可以在某些调用站点内联,而在其他站点不能内联,只需让编译器完成它的工作。您可以使用-Os进行编译以减少内联。
标签: c++ templates c++11 linker