我有一个带静态函数的模板类(参见下面的连接函数)。此模板类是第三方库(称为LibA)的一部分。我的代码使用此lib并包含下面的标题,因为我需要使用模板类。当我编译我的lib没有内联函数(-fno-default-inline with gcc)时,我没有遇到任何问题。当我在发行版(-O2)中编译时,我的应用程序崩溃了。
我想知道在模板中使用静态函数会产生什么影响以及内联如何影响这一点。
template<class T>
class TCPConnector
: public IOHandler {
private:
string _ip;
uint16_t _port;
vector<uint32_t> _protocolChain;
bool _closeSocket;
Variant _customParameters;
public:
TCPConnector(int32_t fd, string ip, uint16_t port,
vector<uint32_t>& protocolChain, const Variant& customParameters)
: IOHandler(fd, IOHT_TCP_CONNECTOR) {
_ip = ip;
_port = port;
_protocolChain = protocolChain;
_closeSocket = true;
_customParameters = customParameters;
}
virtual ~TCPConnector() {
//FINEST("Close socket: %d", _closeSocket);
if (_closeSocket) {
close(_fd);
//FINEST("Socket closed!");
}
}
static bool Connect(string ip, uint16_t port,
vector<uint32_t>& protocolChain, Variant& customParameters) {
protoent *pProtocol = getprotobyname("IP");
if (pProtocol == NULL) {
FATAL("Unable to resolve protocol number for IP");
return 0;
}
int32_t fd = (int32_t) socket(PF_INET, SOCK_STREAM, pProtocol->p_proto);
if (fd <= 0) {
FATAL("Unable to create fd");
return 0;
}
if (!SetFdNonBlock(fd)) {
FATAL("Unable to put socket in non-blocking mode");
return false;
}
TCPConnector<T> *pTCPConnector = new TCPConnector(fd, ip, port,
protocolChain, customParameters);
if (!pTCPConnector->Connect()) {
IOHandlerManager::EnqueueForDelete(pTCPConnector);
FATAL("Unable to connect");
return false;
}
return true;
}
};
答案 0 :(得分:1)
我不认为崩溃与您使用模板,静态或内联这一事实有关。至少在这种特殊情况下。
您应该尝试找出崩溃的原因,例如:通过分析转储。
答案 1 :(得分:1)
您提示您认为该库包含该功能。检查一下。如果是这样,那肯定是一个错误。
检查您的库文件的标题是否正确。
如果失败了,能够使用库的修复可能是从头中删除定义,因此它不再内联。这将有效地使其成为extern
(非export
)模板化函数,因此您只能在库.o
中使用特化。
至于你想知道的是,静态成员函数与自由函数的链接非常相似。如果它是内联的,则无法从库文件中调用。否则,static
基本上与extern
的含义相同:在任何地方只有一个副本。
答案 2 :(得分:1)
我同意David Alfonso的说法,即崩溃可能与您使用此“库”的事实无关。
此“库”还包含几个与崩溃无关的问题:
答案 3 :(得分:0)
没关系。类静态函数是关于是否需要类的实例来调用函数。实际上,非静态方法和静态方法之间的主要区别是前者具有额外的“隐藏”功能参数。
由于您遇到崩溃,您是否已确定代码的哪一部分实际导致崩溃?