我有最简单的代码,我想在三个文件中分开:
当我即将实现operator[]
方法时,我无法编译它。这是一个显示相同问题的最小示例:
标题(myclass.h
):
#ifndef _MYCLASS_H_
#define _MYCLASS_H_
class MyClass
{
public:
MyClass(const int n);
virtual ~MyClass();
double& operator[](const int i);
double operator[](const int i) const;
void someBigMethod();
private:
double* arr;
};
#endif /* _MYCLASS_H_ */
内联函数(myclass-inl.h
):
#include "myclass.h"
inline double& MyClass::operator[](const int i) {
return arr[i];
}
inline double MyClass::operator[](const int i) const {
return arr[i];
}
代码(myclass.cpp
):
#include "myclass.h"
#include "myclass-inl.h"
#include <iostream>
inline MyClass::MyClass(const int n) {
arr = new double[n];
}
inline MyClass::~MyClass() {
delete[] arr;
}
void MyClass::someBigMethod() {
std::cout << "Hello big method that is not inlined" << std::endl;
}
最后,主要测试一切:
#include "myclass.h"
#include <iostream>
using namespace std;
int main(int argc, char *argv[]) {
MyClass m(123);
double x = m[1];
m[1] = 1234;
cout << "m[1]=" << m[1] << endl;
x = x + 1;
return 0;
}
void nothing() {
cout << "hello world" << endl;
}
当我编译它时,它说:
main.cpp:(.text+0x1b): undefined reference to 'MyClass::MyClass(int)'
main.cpp:(.text+0x2f): undefined reference to 'MyClass::operator[](int)'
main.cpp:(.text+0x49): undefined reference to 'MyClass::operator[](int)'
main.cpp:(.text+0x65): undefined reference to 'MyClass::operator[](int)'
但是,当我将main
方法移动到MyClass.cpp
文件时,它可以正常工作。你能帮助我发现问题吗?
谢谢。
答案 0 :(得分:6)
用于测试设置的主程序文件不包含带有内联成员函数的头文件。由于函数是内联函数,因此它们不包含在从myclass.cpp
生成的目标文件中。
内联函数不可用于编译器,因此它认为调用是外部的;但它们也不可用于链接器,因为它们不会在其他地方生成独立定义。
如果您希望函数内联,只需将它们放在myclass.h
。
答案 1 :(得分:3)
您必须在头文件中定义内联函数,而不是在不同的编译单元中。否则,编译器如何内联它们呢?当编译器看到一个应该是内联函数的调用时,它必须知道它的定义,因此它可以内联它而不是标记对链接器的调用。
我可以提供的最佳解决方案是从这些功能中完全删除内联关键字。仅当您具有支持决策的具体分析器编号时,或者当函数体为零到一行代码时,才内联函数。
答案 2 :(得分:0)
您需要在main.cpp中包含myclass-inl.h
不推荐在三个文件中拆分代码。
答案 3 :(得分:-2)
问题在于链接。当你链接可执行文件时,你包括myclass.o?你也需要编译它。