实体组件系统未定义的符号

时间:2017-05-21 13:22:24

标签: c++ entity-component-system

我是c ++的新手,我试图用sfml创建一个游戏,在这个游戏中我试图使用一个实体组件系统,我可以用于这个游戏和游戏的更进一步,但当我编译我得到一个错误,我不知道如何解决它。

这是我的entity.hpp类:

#ifndef Entity_hpp
#define Entity_hpp

#include <stdio.h>
#include <iostream>
#include <vector>
#include <Component.hpp>

using namespace std;

class Entity {

private:
    vector<unique_ptr<Component>> _components;
public:
    void Start();
    void Update();
    void Draw();

    template <typename T, typename... TArgs> T& AddComponent(TArgs... args);
    template <typename T> T& GetComponent();
};

#endif /* Entity_hpp */

接下来是Entity.cpp类:

#include "Entity.hpp"

void Entity::Update() {
    for (auto& c : _components) {
        c->Update();
    }
}

void Entity::Draw() {
    for (auto& c : _components) {
        c->Draw();
    }
}

void Entity::Start() {
    for(auto& c : _components) {
        c->Start();
    }
}

template <typename T, typename... TArgs>
T& Entity::AddComponent(TArgs... args) {
    T* component(new T(forward<T>(args)...));

    component->entity = this;

    unique_ptr<T> ptr{component};
    _components.emplace_back(move(ptr));

    return *component;
}

template <typename T> T& Entity::GetComponent() {
    T* c;

    if(find(_components.begin(), _components.end(), c) != _components.end()) {
        return &c;
    }

    return nullptr;
}

我添加组件的游戏类:

#include "Game.hpp"

void Game::Start() {
    auto& entity(_system.AddEntity());
    auto& m(entity.AddComponent<Movement>());
}

void Game::Update() {

}

最后我的组件及其父组件:

#ifndef MovementComponent_hpp
#define MovementComponent_hpp

#include <stdio.h>

#include <Component.hpp>

class Movement : Component {

public:
    Movement() {};

    void Start() override {};
    void Update() override {};
    void Draw() override {};
};

#endif /* MovementComponent_hpp */

两者都没有在cpp文件中实现

#ifndef Component_hpp
#define Component_hpp

#include <stdio.h>

using namespace std;

class Entity;

class Component {

public:
    Entity* entity{nullptr};
    virtual void Start();
    virtual void Update();
    virtual void Draw();
    virtual ~Component();
};


#endif /* Component_hpp */

这就是我得到的错误:

Ld /Users/joeywelvaadt/Library/Developer/Xcode/DerivedData/SFML-eeksqjpmpgsdomeiuuzvucxhodww/Build/Products/Debug/SFML.app/Contents/MacOS/SFML normal x86_64
    cd /Users/joeywelvaadt/Desktop/XCode/C++/SFML
    export MACOSX_DEPLOYMENT_TARGET=10.7
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -L/Users/joeywelvaadt/Library/Developer/Xcode/DerivedData/SFML-eeksqjpmpgsdomeiuuzvucxhodww/Build/Products/Debug -L/usr/local/lib -F/Users/joeywelvaadt/Library/Developer/Xcode/DerivedData/SFML-eeksqjpmpgsdomeiuuzvucxhodww/Build/Products/Debug -F/Library/Frameworks -filelist /Users/joeywelvaadt/Library/Developer/Xcode/DerivedData/SFML-eeksqjpmpgsdomeiuuzvucxhodww/Build/Intermediates/SFML.build/Debug/SFML.build/Objects-normal/x86_64/SFML.LinkFileList -Xlinker -rpath -Xlinker @loader_path/../Frameworks -mmacosx-version-min=10.7 -Xlinker -object_path_lto -Xlinker /Users/joeywelvaadt/Library/Developer/Xcode/DerivedData/SFML-eeksqjpmpgsdomeiuuzvucxhodww/Build/Intermediates/SFML.build/Debug/SFML.build/Objects-normal/x86_64/SFML_lto.o -stdlib=libc++ -fobjc-link-runtime -framework sfml-system -framework sfml-window -framework sfml-graphics -framework sfml-audio -framework sfml-network -Xlinker -dependency_info -Xlinker /Users/joeywelvaadt/Library/Developer/Xcode/DerivedData/SFML-eeksqjpmpgsdomeiuuzvucxhodww/Build/Intermediates/SFML.build/Debug/SFML.build/Objects-normal/x86_64/SFML_dependency_info.dat -o /Users/joeywelvaadt/Library/Developer/Xcode/DerivedData/SFML-eeksqjpmpgsdomeiuuzvucxhodww/Build/Products/Debug/SFML.app/Contents/MacOS/SFML

Undefined symbols for architecture x86_64:
  "Movement& Entity::AddComponent<Movement>()", referenced from:
      Game::Start() in Game.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

1 个答案:

答案 0 :(得分:0)

模板声明和定义应该保留在同一个文件中(好吧,或多或少,你也可以通过在标题的末尾包含实现文件来以某种方式将它们分开,但为了清楚起见,让我简化这个问题)。您的Entity::AddComponent成员函数不是这种情况,因此错误 如果你想使用像模板系统这样的功能,我建议你更深入一点 话虽如此,将您的成员模板函数的定义移至.hpp并再试一次。