使用 C++ 解决状态模式中的循环依赖问题

发布于 2024-10-20 03:16:54 字数 3223 浏览 0 评论 0原文

我正在尝试在 C++ 中实现状态模式,但存在循环依赖问题。我在这里阅读了其他相关材料 - 不幸的是它对我没有帮助。我对 C++ 没有太多经验,所以请耐心等待。 以下代码是在 Ubuntu 10.10 机器上的 Eclipse Helios CDT 中开发的:

ConcreteSystem.h

#ifndef CONCRETESYSTEM_H_
#define CONCRETESYSTEM_H_

class SystemState;

class ConcreteSystem {
public:
    ConcreteSystem();
    void SelfTestFailed();
    void Restart();
private:
    friend class SystemState;
    SystemState *currentState;
    void ChangeState(SystemState *state);
};

#endif /* CONCRETESYSTEM_H_ */

ConcreteSystem.cpp

#include "ConcreteSystem.h"
#include "SystemState.h"

ConcreteSystem::ConcreteSystem() {
    currentState = SelfTest::GetInstance();
}

void ConcreteSystem::SelfTestFailed() {
    currentState->SelfTestFailed(this);
}

void ConcreteSystem::Restart() {
    currentState->Restart(this);
}

void ConcreteSystem::ChangeState(SystemState *state){
    currentState = state;
}

SystemState.h

#ifndef SYSTEMSTATE_H_
#define SYSTEMSTATE_H_

class ConcreteSystem;

class SystemState {
public:
    virtual void Restart(ConcreteSystem *cs);
    virtual void SelfTestFailed(ConcreteSystem *cs);
protected:
    virtual void ChangeState(ConcreteSystem *cs, SystemState *state);
};

#endif /* SYSTEMSTATE_H_ */

SystemState。 cpp

#include "SystemState.h"
#include "ConcreteSystem.h"

void SystemState::Restart(ConcreteSystem *cs) {

}

void SystemState::SelfTestFailed(ConcreteSystem *cs) {

}


void SystemState::ChangeState(ConcreteSystem *cs, SystemState *state) {
    cs->ChangeState(state);
}

SelfTest.h

#ifndef SELFTEST_H_
#define SELFTEST_H_

#include "SystemState.h"


class SelfTest : public SystemState {
public:
    SelfTest();
    void SelfTestFailed(ConcreteSystem* cs);
    static SystemState* GetInstance();
private:
    static SystemState* instance;
};

#endif /* SELFTEST_H_ */

SelfTest.cpp

#include "SelfTest.h"
#include "Failure.h"

SystemState* SelfTest::instance = 0;

SelfTest::SelfTest() {

}

void SelfTest::SelfTestFailed(ConcreteSystem *cs) {
    ChangeState(cs, Failure::GetInstance());
}

SystemState* SelfTest::GetInstance() {
    if (instance == 0) {
        instance = new SelfTest();
    }
    return instance;
}

Failure.h

#ifndef FAILURE_H_
#define FAILURE_H_

#include "SystemState.h"

class SelfTest;

class Failure : public SystemState {
public:
    Failure();
    void Restart(ConcreteSystem* t);
    static SystemState* GetInstance();
private:
    static SystemState* instance;
};

#endif /* FAILURE_H_ */

Failure.cpp

#include "Failure.h"
#include "SelfTest.h"

SystemState* Failure::instance = 0;

Failure::Failure() {

}

void Failure::Restart(ConcreteSystem* t) {
    ChangeState(t, SelfTest::GetInstance());
}

SystemState* Failure::GetInstance() {
    if (instance == 0) {
        instance = new Failure();
    }
    return instance;
}

我有问题包括,这给了我一些奇怪的编译器错误。有谁有好的办法解决这个问题吗?

I'm trying to implement a State Pattern in C++, but have problems with the circular dependency. I have read other related material here - unfortunately it didn't help me. I don't have a lot of experience with C++, so bear with me.
The following code is developed on a Ubuntu 10.10 machine in Eclipse Helios CDT:

ConcreteSystem.h

#ifndef CONCRETESYSTEM_H_
#define CONCRETESYSTEM_H_

class SystemState;

class ConcreteSystem {
public:
    ConcreteSystem();
    void SelfTestFailed();
    void Restart();
private:
    friend class SystemState;
    SystemState *currentState;
    void ChangeState(SystemState *state);
};

#endif /* CONCRETESYSTEM_H_ */

ConcreteSystem.cpp

#include "ConcreteSystem.h"
#include "SystemState.h"

ConcreteSystem::ConcreteSystem() {
    currentState = SelfTest::GetInstance();
}

void ConcreteSystem::SelfTestFailed() {
    currentState->SelfTestFailed(this);
}

void ConcreteSystem::Restart() {
    currentState->Restart(this);
}

void ConcreteSystem::ChangeState(SystemState *state){
    currentState = state;
}

SystemState.h

#ifndef SYSTEMSTATE_H_
#define SYSTEMSTATE_H_

class ConcreteSystem;

class SystemState {
public:
    virtual void Restart(ConcreteSystem *cs);
    virtual void SelfTestFailed(ConcreteSystem *cs);
protected:
    virtual void ChangeState(ConcreteSystem *cs, SystemState *state);
};

#endif /* SYSTEMSTATE_H_ */

SystemState.cpp

#include "SystemState.h"
#include "ConcreteSystem.h"

void SystemState::Restart(ConcreteSystem *cs) {

}

void SystemState::SelfTestFailed(ConcreteSystem *cs) {

}


void SystemState::ChangeState(ConcreteSystem *cs, SystemState *state) {
    cs->ChangeState(state);
}

SelfTest.h

#ifndef SELFTEST_H_
#define SELFTEST_H_

#include "SystemState.h"


class SelfTest : public SystemState {
public:
    SelfTest();
    void SelfTestFailed(ConcreteSystem* cs);
    static SystemState* GetInstance();
private:
    static SystemState* instance;
};

#endif /* SELFTEST_H_ */

SelfTest.cpp

#include "SelfTest.h"
#include "Failure.h"

SystemState* SelfTest::instance = 0;

SelfTest::SelfTest() {

}

void SelfTest::SelfTestFailed(ConcreteSystem *cs) {
    ChangeState(cs, Failure::GetInstance());
}

SystemState* SelfTest::GetInstance() {
    if (instance == 0) {
        instance = new SelfTest();
    }
    return instance;
}

Failure.h

#ifndef FAILURE_H_
#define FAILURE_H_

#include "SystemState.h"

class SelfTest;

class Failure : public SystemState {
public:
    Failure();
    void Restart(ConcreteSystem* t);
    static SystemState* GetInstance();
private:
    static SystemState* instance;
};

#endif /* FAILURE_H_ */

Failure.cpp

#include "Failure.h"
#include "SelfTest.h"

SystemState* Failure::instance = 0;

Failure::Failure() {

}

void Failure::Restart(ConcreteSystem* t) {
    ChangeState(t, SelfTest::GetInstance());
}

SystemState* Failure::GetInstance() {
    if (instance == 0) {
        instance = new Failure();
    }
    return instance;
}

I have problem with the includes, which gives me some weird compiler errors. Anyone with a good solution to this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夏雨凉 2024-10-27 03:16:54

从您发布的代码来看,您将重新定义类。查看 Failure.cpp 文件,您可以看到:

#include "Failure.h"
#include "SelfTest.h"

其中将包含这两个文件,并且每个文件都包含 SystemState.h 文件。由于 SystemState.h 文件被多次包含,因此它会尝试重新定义 SystemState 类。在每个头文件的顶部,您应该执行以下操作:

// SystemState.h
#ifndef SystemState_h
#define SystemState_h
.. class definition ..
#endif // close the if statement from above.

作为设计的旁白,我认为各州相互了解是一种不好的形式 - 使用您的 ConcreteSystem 作为状态控制器,然后将状态基于最后一个状态操作的返回值。

另外,如果您对 C++ 相对缺乏经验,我建议您查看这是学习材料的重要来源(当然,除了 StackOverflow!)。

From the looks of the code you've posted, you'll have classes being redefined. Looking at your Failure.cpp file, you have:

#include "Failure.h"
#include "SelfTest.h"

Which will include both of those files, and each of those files include the SystemState.h file. Since the SystemState.h file is included more than once, it tries to redefine the SystemState class. At the top of each of your header files, you should do something like this:

// SystemState.h
#ifndef SystemState_h
#define SystemState_h
.. class definition ..
#endif // close the if statement from above.

As an aside on the design, I think it's bad form for the states to know about each other - use your ConcreteSystem as a state controller and then base the state on the return value of the last state operation.

Also, if you're relatively inexperienced with C++, I would recommend looking at this as a great source of learning material (in addition to StackOverflow, of course!).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文