我正在创建一些类来封装套接字IO。我已经创建了一个基类来抽象出常见数据(文件描述符,端口#s等)和功能(大部分初始化)。我的代码看起来像这样 -
base.hpp
class Base {
protected:
Base(int port);
~Base();
// common data
};
Also here I have the implementations of the constructor and destructor
client.hpp
#include base.hpp
class Client : private Base {
// constructor and other required code
}
testclient.cpp
#include "client.cpp"
int main() {
Client c (ip, port);
... more stuff
return 0;
}
我还在client.cpp中实现了客户端类,并且它的构造函数适当地调用了基本构造函数。我也有正确而独特的头部防护。但是,当将client.o与testclient链接时,我会引用链接器错误,引用Base构造函数和析构函数的多个定义。我究竟做错了什么?我会包含代码,但它很长,我确信我的错误是由于一些#include / linked magic。
答案 0 :(得分:1)
如果函数在头文件中实现,则必须使用inline
声明函数的定义,以防止对函数进行多种定义。
修复将inline
放在实现前面的错误。例如,Base
的构造函数
inline Base::Base(int port)
^^^^^^ Difference here
{
// Implementation
}
您也可以在类中实现方法。
inline
通知编译器该函数可以在多个.cpp文件中编译(在类定义中声明的函数是隐式声明的inline
。)如果函数未声明为{{1}它从每个.cpp文件导出。当链接器出现时,在编译程序之后,每个.cpp文件中都有一个包含标题的函数定义。这会导致链接器出错。
答案 1 :(得分:0)
在标头文件client.hpp
中:
class Base {
protected:
Base(int port) {
...
}
~Base() {
...
}
};
在标头文件client.hpp
中:
class Base {
protected:
Base(int port);
~Base();
};
在源文件client.cpp
中:
Base::Base(int port) {
...
}
Base::~Base() {
...
}
答案 2 :(得分:0)
#include base.hpp
应为此#include "base.hpp"
或#include "base.h"