C++ 对自己文件的未定义引用

C++ 对自己文件的未定义引用,c++,linker-errors,C++,Linker Errors,我有以下Makefile来制作我的项目: # can be set by the user LD_FLAGS ?= $(if $(GENERATE_EXECUTABLE),,-shared) LIBS_FLAGS ?= INCLUDE_FLAGS ?= CXX_FLAGS ?= -O3 -Wall -std=c++11 objects = Connector.cpp main.cpp defines := $(objects:.o=.def) -include $(defines) # mai

我有以下Makefile来制作我的项目:

# can be set by the user
LD_FLAGS ?= $(if $(GENERATE_EXECUTABLE),,-shared)
LIBS_FLAGS ?=
INCLUDE_FLAGS ?=
CXX_FLAGS ?= -O3 -Wall -std=c++11

objects = Connector.cpp main.cpp
defines := $(objects:.o=.def)
-include $(defines)
# main target
bin/o.exe: $(objects)
    @echo '[LD] $^ > $@'
    $(CXX) $(LD_FLAGS) $^ -o $@ $(LIBS_FLAGS)

define generate_def
echo '[DEF] $< > $@'
$1 -MM $(INCLUDE_FLAGS) $2 $< > $@
mv -f $@ $@.tmp
sed -e 's|.*:|$@:|' < $@.tmp > $@
sed -e 's/.*://' -e 's/\\$$//' < $@.tmp | fmt -1 | \
    sed -e 's/^ *//' -e 's/$$/:/' >> $@
rm -f $@.tmp
endef
# Compile C++-Files with an appropriate def-file
obj/c++/%.def: %.cpp
    @$(call generate_def,$(CXX),$(CXX_FLAGS))
$(objectscxx): obj/c++/%.o: %.cpp obj/c++/%.def # C++-Files
    @echo '[CXX] $< > $@'
    $(CXX) -c $< $(INCLUDE_FLAGS) $(CXX_FLAGS) -o $@

all: bin/o.exe
#可由用户设置
LD_标志?=$(如果$(生成_可执行文件),,-共享)
自由旗帜=
包括国旗=
CXX_标志?=-O3-Wall-std=c++11
对象=Connector.cpp main.cpp
定义:=$(对象:.o=.def)
-包含$(定义)
#主要目标
bin/o.exe:$(对象)
@回显“[LD]$^>$@”
$(CXX)$(LD_标志)$^-o$@$(LIBS_标志)
定义生成定义
回显“[DEF]$<>$@”
$1-MM$(包括旗帜)$2$<>$@
mv-f$@$@.tmp
sed-e的|*:|$@:|'<$@.tmp>$@
sed-e's/*:/'-e's/\\$$/'<$@.tmp|fmt-1|\
sed-e's/^*/'-e's/$$/:/'>>$@
rm-f$@.tmp
恩德夫
#使用适当的def文件编译C++文件
obj/c++/%.def:%.cpp
@$(调用generate_def,$(CXX),$(CXX_标志))
$(objectscxx):obj/c++/%.o:%.cpp obj/c++/%.def#c++-文件
@回显“[CXX]$<>$@”
$(CXX)-c$<$(包括_标志)$(CXX_标志)-o$@
全部:bin/o.exe
main.cpp包括Connector.h,Connector.cpp实现Connector.h中声明的函数。在链接阶段之前,一切都很好

现在,当我运行它时,输出如下:

make all
[DEF] src/main.cpp > obj/c++/src/main.def
[DEF] src/Connector.cpp > obj/c++/src/Connector.def
[CXX] src/Connector.cpp > obj/c++/src/Connector.o
g++ -c src/Connector.cpp -O3 -Wall -g -std=c++11 -o obj/c++/src/Connector.o
[CXX] src/main.cpp > obj/c++/src/main.o
g++ -c src/main.cpp -O3 -Wall -g -std=c++11 -o obj/c++/src/main.o
[LD] obj/c++/src/Connector.o obj/c++/src/main.o obj/res/test.txt.o > bin/o.exe
g++ -static obj/c++/src/Connector.o obj/c++/src/main.o obj/res/test.txt.o -o bin/o.exe 
obj/c++/src/main.o: In function `SpecialConnector::~SpecialConnector()':
C:\Users\Carbon\Documents\Eclipse-Workbench\EpicRPG/src/main.cpp:35: undefined reference to `engine::Connector<SpecialReceiver>::~Connector()'
/**
* More undefined references
*/
obj/c++/src/main.o:C:\Users\Carbon\Documents\Eclipse-Workbench\EpicRPG/src/main.cpp:35: more undefined references to `engine::Connector<SpecialReceiver>::~Connector()' follow
collect2.exe: error: ld returned 1 exit status
make: *** [bin/o.exe] Error 1
makeall
[DEF]src/main.cpp>obj/c++/src/main.DEF
[DEF]src/Connector.cpp>obj/c++/src/Connector.DEF
[CXX]src/Connector.cpp>obj/c++/src/Connector.o
g++-csrc/Connector.cpp-O3-Wall-g-std=c++11-o obj/c++/src/Connector.o
[CXX]src/main.cpp>obj/c++/src/main.o
g++-csrc/main.cpp-O3-Wall-g-std=c++11-o obj/c++/src/main.o
[LD]obj/c++/src/Connector.o obj/c++/src/main.o obj/res/test.txt.o>bin/o.exe
g++-static obj/c++/src/Connector.o obj/c++/src/main.o obj/res/test.txt.o-o bin/o.exe
obj/c++/src/main.o:在函数'SpecialConnector::~SpecialConnector()'中:
C:\Users\Carbon\Documents\Eclipse Workbench\EpicRPG/src/main.cpp:35:对'engine::Connector::~Connector()的未定义引用
/**
*更多未定义的引用
*/
obj/c++/src/main.o:c:\Users\Carbon\Documents\Eclipse Workbench\EpicRPG/src/main.cpp:35:下面是对“engine::Connector::~Connector()”的更多未定义引用
collect2.exe:错误:ld返回了1个退出状态
生成:**[bin/o.exe]错误1
连接器.h

/*
 * Connector.h
 *
 *  Created on: 03.06.2014
 *      Author: Carbon
 */

#pragma once
#ifndef CONNECTOR_H_
#define CONNECTOR_H_

#include <type_traits>

namespace engine
{
template<typename DataType, typename ConnectorType>
struct DefaultReceiver {
public:
    DefaultReceiver() {

    }
    virtual ~DefaultReceiver() {

    }

    static const char* receive(DataType data, ConnectorType conn, void* options) {
        return "b";
    }
};

template<template<typename, typename> class Receiver = DefaultReceiver>
class Connector
{
public:
    Connector();
    virtual ~Connector();

    template<typename DataType, typename ConnectorType>
    std::enable_if<true, const char*>::type
    receive(DataType i, ConnectorType c, void* o);
};

} /* namespace engine */
#endif /* CONNECTOR_H_ */
/*
*连接器.h
*
*创建日期:2014年6月3日
*作者:碳
*/
#布拉格语一次
#ifndef连接器_
#定义连接器_
#包括
名称空间引擎
{
模板
结构DefaultReceiver{
公众:
DefaultReceiver(){
}
虚拟~DefaultReceiver(){
}
静态常量字符*接收(数据类型数据、连接器类型连接、无效*选项){
返回“b”;
}
};
模板
类连接器
{
公众:
连接器();
虚拟连接器();
模板
std::enable_if::type
接收(数据类型i,连接器类型c,无效*o);
};
}/*命名空间引擎*/
#endif/*连接器*/
连接器.cpp

/*
 * Connector.cpp
 *
 *  Created on: 03.06.2014
 *      Author: Carbon
 */

#include "Connector.h"

namespace engine
{
template<template<typename, typename> class Receiver>
Connector<Receiver>::Connector()
{
    // TODO Auto-generated constructor stub

}
template<template<typename, typename> class Receiver>
Connector<Receiver>::~Connector()
{
    // TODO Auto-generated destructor stub
}

template<template<typename, typename> class Receiver>
template<typename DataType, typename ConnectorType>
std::enable_if<true, const char*>::type
Connector<Receiver>::receive(DataType input, ConnectorType connector, void* options) {
    return Receiver<DataType, ConnectorType>::receive(input, connector, options);
}
} /* namespace engine */
/*
*连接器.cpp
*
*创建日期:2014年6月3日
*作者:碳
*/
#包括“Connector.h”
名称空间引擎
{
模板
连接器::连接器()
{
//TODO自动生成的构造函数存根
}
模板
连接器::~连接器()
{
//TODO自动生成的析构函数存根
}
模板
模板
std::enable_if::type
连接器::接收(数据类型输入、连接器类型连接器、void*选项){
返回接收器::接收(输入、连接器、选项);
}
}/*命名空间引擎*/
如果您需要源文件,请发表评论,我认为没有必要(是的,所有函数等都声明了,如果我包括Connector.cpp而不是Connector.h,一切都很好)


我的规范是:EclipseM4.3,gcc版本4.8.0

此编译错误与模板实例化有关。要解决此问题,可以将类
Connector
的实现放入头文件中


这对原因给出了很好的解释,请查看。

大多数编译器需要在源文件中定义模板
连接器
(或者在源文件中重新声明模板类)

特别是,构造函数和析构函数应该在头文件中定义(仅声明)

在连接器h中:

template<template<typename, typename> class Receiver = DefaultReceiver>
class Connector
{
public:
    Connector() {}
    virtual ~Connector() {}

    template<typename DataType, typename ConnectorType>
    std::enable_if<true, const char*>::type
    receive(DataType i, ConnectorType c, void* o) {}
};
模板
类连接器
{
公众:
连接器(){}
虚拟~Connector(){}
模板
std::enable_if::type
接收(数据类型i,连接器类型c,void*o){}
};

请显示engine::ConnectorTanks的源代码和标题,以链接到其他问题。这也是为什么这是公认的答案。