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

标签 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)
# 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

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

连接器.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_ */

连接器.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 */

如果您需要源文件,请发表评论,我认为没有必要(是的,声明了所有函数等,如果我包含 Connector.cpp 而不是 Connector.h,一切都很好)。

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

最佳答案

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

answer原因解释得很好,请看一下。

关于c++ - 未定义的对自己文件的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24024246/

相关文章:

c++ - fatal error : botan/botan. h:没有那个文件或目录

C++ 链接器错误 : undefined references only on optimized build

c++ - 如何在 Microsoft Visual C++ 中导入 dllimport

c++ - 带参数的非空函数的空包装

c++ - 没有任何功能的 C++ 多态类是否可能?

c++ - std::string 转换为 char32_t(unicode 字符)

c++17,lto,-static-libstdc++ 问题 : Warning: relocation refers to discarded section with ld. gold,然后在 __run_exit_handlers 中出现段错误

c++ - 如果 try-catch block 被证明是非抛出的,编译器必须始终删除它

c++ - Qt, "Paint"中的resizeEvent

尝试从使用 makefile 生成的目标文件构建时出现 C++ 链接器错误。当我刚刚构建它时不会发生