C ++类保存并返回指向另一个类的指针

时间:2014-04-07 02:12:36

标签: c++ class pointers arduino

我一直想弄清楚Class如何存储和检索Class指针。(?)

我从导入的库中获得了一个有限状态机类。当我想改变状态时,我这样做:

// Set up my State instance
void fooEntry();
void fooUpdate();
void fooExit();
// Instantiate State object
State fooState(fooEntry,fooUpdate,fooExit);
// Instantiate FSM object
FiniteStateMachine stateMachine = FiniteStateMachine(fooState);
// Transition to this State
statemachine.transitionTo(fooState);

这很好用。我希望某些State实例做更多的事情,包括hold和return a State,所以我补充说:

class MyState: public State {
  public:
    MyState(void (*enterFunction)(), void (*updateFunction)(), void (*exitFunction)());
    // Save a State's address to a State pointer
    void setNextState(const State &state) {*followingState = state;} 
    State * nextState() { return followingState;} // Return pointer?
    // Lot's more not pertinent to this question.
  private:
    State * followingState;
};

我希望能够做到这一点:

// Set up and instantiate my MyState instance
void barEntry();
void barUpdate();
void barExit();
MyState barState(barEntry(),barUpdate(),barExit());
barState.setNextState(fooState); // Pass it the next State I want to go to
// then later...
statemachine.transitionTo(barState.nextState()); // retrieve the State.

当我尝试编译时,我收到如下错误:

error: no matching function for call to 'FiniteStateMachine::transitionTo(State*)'
note: candidates are: FiniteStateMachine& FiniteStateMachine::transitionTo(State&)

这是从我致电statemachine.transitionTo(barState.nextState);的时候起我已经尝试了&的所有组合和*我可以想到让它编译(更少的工作),直到我猜测。我希望有人能指出我的错误,也许会向我解释。

我不确定这是否重要,因为我只是在教自己C / C ++(20年太晚了),但这是在arduino上运行。


EDIT1

所以在我做了@deviantfan建议的更改后,编译了代码,但每当我到达

barState.setNextState(fooState); 

该程序存在某种内存问题,并跳转到程序的另一个随机部分,然后崩溃。这应该只是呼唤:

void setNextState(const State &state) {*followingState = state;} 

所以我不确定为什么我的程序会变得疯狂。但事实并非如此,我已经在其他地方对数组和/指针进行了粗心的处理。


EDIT2

我发现了一些问题的原因(写了一个非常错误的地址),但是当我尝试使用getFollowingState返回的对象地址时,它仍然崩溃了。我现在拥有的:

class MyState: public State {
  public:
    MyState(void (*enterFunction)(), void (*updateFunction)(), void (*exitFunction)());
    // Save a State's address to a State pointer
    void setFollowingState(State &state) {followingState = &state;} // followingState should be a pointer to a State object.
    State * getFollowingState() { return followingState;} // Return pointer?
    // Lot's more not pertinent to this question.
  private:
    State * followingState; // a pointer to a state object.
};

要使用它,我会这样做:

// Set up and instantiate my MyState instance
void barEntry();    void barUpdate();    void barExit();
MyState barState(barEntry(),barUpdate(),barExit());
barState.setFollowingState(fooState); // Pass it the next State I want to go to
statemachine.transitionTo(barState);
// then later within one of fooState's functions, 
statemachine.transitionTo(*barState.getFollowingtState()); // retrieve the State.

1 个答案:

答案 0 :(得分:2)

这条线可能没有达到你的期望:

void setNextState(const State &state) {*followingState = state;} 

当您编写*followingState时,您将取消引用指针。这意味着它访问了指向的对象,而不是指针本身。因此,该功能不会复制state的地址。相反,它试图制作其内容的全新副本,并将其放入followingState指向的任何内容中。

这是一个问题,因为看起来followingState实际上并没有指向任何东西 - 它可能是一个空的或狂野的(无效的)指针。这意味着您的函数最终会将数据复制到内存中的某个任意位置,从而导致未定义的行为。

相反,您要复制state地址而不是其内容,如下所示:

void setNextState(const State &state) { followingState = &state; }

为了做到这一点,您需要将followingState的声明更改为const State * followingState;。在这种情况下,const表示指针可以重新分配给不同的对象,但指向的对象不能被修改。

如果您希望能够修改状态,则需要从const参数列表中删除setNextState()