循环依赖:无法删除不完整的类型

时间:2017-06-19 14:50:51

标签: c++ oop smart-pointers

我不明白为什么会出现这个编译错误:

error C2027: use of undefined type 'GameState'
note: see declaration of 'GameState'
error C2338: can't delete an incomplete type warning C4150: deletion of pointer to incomplete type 'GameState'; no destructor called

这是相关代码:

#pragma once
#include <SFML\Graphics.hpp>
#include "SpawnManager.h"
#include "Resource.h"
#include <stack>
#include <memory>
class GameState;

class Controller
{
public:
    Controller();
    void run();
    void setPlayerScore(unsigned score);
    sf::RenderWindow& getWindow() { return m_window; }
    void addState(const States& state);
    void changeState(const States& state);
    GameState* getState() const;
    void popState();
    void add_state(const States& type, Controller * cont);
    ~Controller() {}

private:
    SpawnManager<States, GameState> m_sFactory;
    sf::RenderWindow m_window;
    ScoreRecord m_playerScore;
    std::stack<std::unique_ptr<GameState>> m_screens;
};

#pragma once
#include <SFML\Graphics.hpp>
#include <memory>
#include "Controller.h"

//State design pattern
class GameState
{
public:
    explicit GameState(Controller* state_holder);
    GameState(const GameState&) = delete;
    GameState(GameState&&) = delete;
    GameState& operator=(const GameState&) = delete;
    GameState& operator=(GameState&&) = delete;
    virtual ~GameState() = default;

    virtual void displayState() = 0;
    virtual void updateStage() = 0;
    virtual void handleEvent(sf::Event& event) = 0;

protected:
    std::unique_ptr<Controller> m_state;
};

任何想法如何解决这个问题?

1 个答案:

答案 0 :(得分:8)

std::unique_ptr<T>的析构函数的定义要求T完整,即定义,而不仅仅是声明。由于std::unique_ptr<GameState>Controller的(n间接)成员,因此析构函数~Controller的定义需要定义std::unique_ptr<GameState>的析构函数,因此也需要定义GameState 1}},没有提供。

解决方案:在定义GameState之前定义~Controller。一个最小的例子:

struct GameState;

// 1. Definition of Controller
struct Controller
{
    ~Controller();
    std::stack<std::unique_ptr<GameState>> m_screens;
};

// 2. Definition of GameState
struct GameState
{
    std::unique_ptr<Controller> m_state;
};

// 3. Definition of ~Controller::~Controller
Controller::~Controller(){} // or = default;

P.S。请注意,GameState指向同一Controller的{​​{1}}永远不会指向GameState。在这种情况下,您最终会对已经被破坏的对象进行无限递归。并且多个GameStates不能拥有相同的Controller,反之亦然。考虑您的所有权结构是否有意义。我怀疑你需要共享所有权或非拥有推荐。