状态机、子类和函数指针

Posted

技术标签:

【中文标题】状态机、子类和函数指针【英文标题】:State Machines, Sub-Classes, and Function Pointers 【发布时间】:2013-02-25 01:57:08 【问题描述】:

我在为班级实施状态机时遇到了麻烦。我不断收到错误:

state.cpp:5: error: have0 was not declared in this scope 
state.cpp:10: error: redefinition of State* Have0State::process(std::string)
state.h:18: error: virtual State* Have0State::process(std::string) previously defined here

在继续使用机器的其余部分之前,我试图让 Have0State 工作,因此代码稀疏。

state.h:

#ifndef STATE_H
#define STATE_H

#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <iostream>


class State
    public:
        State();
        virtual State* process(std::string input) = 0;


;
class Have0State: public State 
    public:
        Have0State():State();
        virtual State* process(std::string input);
have0;
#endif

state.cpp:

#include "state.h"

using namespace std;
State *currentState = &have0;

State* Have0State::process(string input)
    if(input == "quarter")
        cout << "cool" << endl;
    
    return &have0;


int main(int argc, char** argv) 
    string input;
    //get input
    cin >> input;
    while (input != "exit") 
        currentState = currentState->process(input);
        //get input
        cin >> input;

    
    return 0;
;

我尝试将流程函数定义为Have0State::State::process(string input),但这也不起作用。关于函数指针应该如何工作的任何说明,特别是在子类成员函数的上下文中,我将不胜感激。

编辑:另外,state.h 文件中 Have0State 类声明末尾的 have0 声明到底是什么?它没有明确声明的类型;是否暗示它是 Have0State 类型的??

【问题讨论】:

have0 的定义似乎类似于有时在 C 中定义 struct 变量的方式。非常罕见,并且会在以后引起您的问题(标题中的变量总是如此),因此您应该将其移至其他位置。跨度> state.h 中定义的末尾是否有?否则重构 have0 看看是否有帮助。 您确定向我们展示的代码与生成错误的代码完全相同吗?我只是将代码(头文件的内容和头文件下面的 cpp 文件的内容,省略了#ifndef 守卫)粘贴到在线编译器中,它编译得很好。 @KarthikT 没有。我没有看到相应的左括号,所以我认为分号就是它所需要的全部 @MaciejHehl 是的,刚刚再次检查... 【参考方案1】:

您的示例中没有任何函数指针。此外,像 Marciej 一样,我能够编译(并运行)这段代码。

但是,既然你问了,'have0' 声明只是声明了一个类的实例。一个类定义后面可以跟 0 个或多个这样的声明(以及初始化器):

class Thing ... one, another, many[3] =  Thing(1), Thing(2), Thing(3) ;

与任何其他类型相同:

int counter = 0, flag = 0x80, limit = 500;

这个可选的声明器列表的可能性是为什么类、结构、联合和枚举定义必须后跟分号(以终止列表)。

但是,正如 Karthik 所说,如果标头包含在多个 .cpp 文件中,则在标头中定义变量将导致链接时出现“重复定义”错误。 IMO 可以使用这种技术在 .cpp 文件(而不是 .h 文件)中定义和声明私有对象。

【讨论】:

以上是关于状态机、子类和函数指针的主要内容,如果未能解决你的问题,请参考以下文章

C函数指针状态机实现

涉及函数指针和状态机的代码解释

父类子类指针相互转换问题

QEP之init()和dispatch()流程图

基类的函数指针指向子类的成员函数?

如何删除在函数中使用父指针作为形参的子类指针?