我不想为每个简单的c ++类编写.cpp
文件。
当我在单个.hpp
文件中编写类定义和声明时,
链接器抱怨成员函数的多个定义,这些定义没有在类的主体内部实现。
所以我使用模板来摆脱链接器投诉:
// log.hpp file
template<typename T>
class log_t {
private:
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;
然后我可以在多个log
文件中使用.cpp
类,而不会有链接器投诉。
这种方法有什么根本原因吗?
编辑:即使我使用此方法,会员功能会成为内联吗?
答案 0 :(得分:5)
如果某个课程不需要成为模板,请不要将其作为模板,只是为了&#34;摆脱链接器的抱怨&#34; 。只需使用适当的编码技术,例如提供成员函数的内联定义:
// log.hpp file
#pragma once
#include <iostream> // For std::cout, std::endl
class log {
private:
static int m_cnt = 0;
public:
log();
};
// Note "inline" here:
inline log::log() {
std::cout << ++m_cnt << std::endl;
}
如果您在课程定义中提供了函数正文,则无需指定关键字inline
:
// log.hpp file
#pragma once
#include <iostream> // For std::cout, std::endl
class log {
private:
static int m_cnt = 0;
public:
// Function body inserted here (no need for "inline"):
log() {
std::cout << ++m_cnt << std::endl;
}
};
答案 1 :(得分:3)
如果您希望在标题中定义函数(包含在多个源文件中,这会导致您的案例中出现多个定义),您应该创建函数inline
。
2个选项:
inline
- 不要将功能定义inline
- 在定义前面手动添加inline
关键字 使用template
只是为了“解决”这个错误并不是一个好主意。仅在需要时使用模板。
答案 2 :(得分:1)
What's wrong with this Method ? Is there something fundamentally wrong with this method ?
不,这种方法没有问题。您需要做的是通过以下方式遵守One Definition Rule:
inline
关键字来使函数定义内联。这是为了避免多个翻译单元中的多个定义(cpp
文件简化一点)实际上,此方法是template
工作的唯一方法。您不能将模板定义放在cpp
文件中,并希望它能够正常工作,因为C++
编译器需要定义来实例化模板。使用template
不是此方法的解决方案,但是如果您希望编译代码,则需要您仅使用此方法。