2013-04-05 56 views
1

我目前正在制作一个游戏,它利用状态堆栈管理器来跟踪所有不同的游戏状态,如主菜单。通过“this”作为参数传递“没有已知的转换”

但是,我遇到了一个我似乎无法解决的问题。

这是状态类,精简到只包含有问题的代码:

class StateManager; 

namespace first { 
namespace second { 

class State { 
    friend class StateManager; 
    protected: 
    /** 
    * Associates the state with the specified state manager instance. 
    * @param stateManager The instance to associate this state with 
    */ 
    void associateWithManager(StateManager *stateManager) { 
     mStateManager = stateManager; 
    } 
    private: 
    StateManager *mStateManager; 
}; 

} // second 
} // first 

以下是状态管理,还剥了下来:

namespace first { 
namespace second { 

class StateManager { 
    public: 
    /** 
    * Adds a state to the stack. 
    * @param state The state to add 
    */ 
    State &add(State &state) { 
     state.associateWithManager(this); 
     return state; 
    } 
}; 

} // second 
} // first 

当我尝试编译此,我得到以下错误(行号有点偏离,因为我有包括警卫等):

src/StateManager.cc: In member function 'State& StateManager::add(State&)': 
src/StateManager.cc:7:34: error: no matching function for call to 'State::associateWithManager(StateManager* const)' 
src/StateManager.cc:7:34: note: candidate is: 
In file included from ./include/StateManager.h:4:0, 
       from src/StateManager.cc:1: 
./include/State.h:29:10: note: void State::associateWithManager(StateManager*) 
./include/State.h:29:10: note: no known conversion for argument 1 from 'StateManager* const' to 'StateManager*' 

显然,this指针被视为const指针,尽管我在add方法中没有使用const关键字。我不确定这里到底发生了什么。 this指针总是const?我很确定我以前用这种方式使用它,但没有问题。

另外,我正在采取这种'正确'的方式吗?或者,当谈到让国家了解经理时,是否有更好的解决方案?也许使用一个单身人士,但我并不是那么喜欢的。

编辑:我现在认识到名称空间之外的前向声明是原因。我是否应该接受Mike的回答,因为它帮助我得出了这个结论?或者我应该发布自己的?

+1

代码没问题。你是否正在声明'StateManager'? – ecatmur 2013-04-05 14:01:15

+0

[适用于我](http://ideone.com/JeS2bc)。这真的是唯一的错误吗? – Angew 2013-04-05 14:01:49

+0

当我发布这个问题时,我剥离了命名空间,但事实证明它实际上没有它们进行编译。我现在正在更新该问题,以显示具有名称空间等的代码。 @ecatmur我确实向前声明了StateManager。 – Merigrim 2013-04-05 14:17:36

回答

2

这是唯一的错误?当我编译它,我第一次得到这个错误:

test.cpp:8:31: error: ‘StateManager’ has not been declared 

当声明一个类是朋友,这个类必须已经声明,否则该声明将被忽略。因此,您需要在定义class State之前在周围的名称空间中声明class StateManager;。随着这一变化,你的代码为我编译。

+0

您的答案帮助我找到了实际问题,请参阅我在问题中的编辑。非常感谢! =) – Merigrim 2013-04-05 14:35:26

+0

@Merigrim:如果你有更好的答案,那么继续并发布它,如果你喜欢。 – 2013-04-05 14:37:28

+0

虽然我可以撰写回答指出具体问题并解决问题,但我认为这样做不一定更好。在这种情况下,即使您的答案如此接近,这是否正确? – Merigrim 2013-04-05 14:42:07

1

this指针不是StateManager *,它是一个StateManager * const

试着改变你的论点的常量性,以StateManager* const stateManager

,如果你不希望你的modifiy调用函数可以随时抛弃的恒定性: state.associateWithManager(const_cast<StateManager*>(this));