0

私はc++を学んでいます。私は Java と Python をよく知っていますが、C++ の試行でちょっとしたデザイン パターンの凝ったものを使うことに腹を立てています。

これが私のファイルです。質問があれば、コメントを歓迎します。

Behaviour を持つクラス Engine があります。Behavior を別の特定の動作にサブクラス化したいのですが、サブクラスがなくても非常に簡単です。

main.cpp :

#include "Engine.h"

int main() {
    Engine e;
    e.work();
    return 0;
};

エンジン.h:

#ifndef ENGINE_H_
#define ENGINE_H_

#include <iostream>
#include "Behaviour.h"

class Engine {

public:

    Engine() {
        std::cout << "Engine constructor" << std::endl;
        this->b = new Behaviour(this);
    };
    virtual ~Engine(){};

    void work() {
        std::cout << "Engine work" << std::endl;
    };

    int getFoo() { return 42; };

private:
    Behaviour * b;
};

#endif /*  ENGINE_H_ */

Behaviour.h :

#ifndef BEHAVIOUR_H_
#define BEHAVIOUR_H_

#include <iostream>
#include "Engine.h"

class Behaviour {

public:

    Behaviour(Engine* e) {
        std::cout << "behaviour constructor, kind of abstract class" << std::endl;
        this->e = e;
    };

    virtual ~Behaviour(){};

    void work() {
        std::cout << "Behaviour work" << this->e->getFoo() << std::endl;
    };

protected:
    Engine * e;

};

#endif /*  BEHAVIOUR_H_ */

私のコンパイラエラー:

$ rm *.gch; c++ *
In file included from Behaviour.h:5:
Engine.h:26: error: ISO C++ forbids declaration of ‘Behaviour’ with no type
Engine.h:26: error: expected ‘;’ before ‘*’ token
Engine.h: In constructor ‘Engine::Engine()’:
Engine.h:14: error: ‘class Engine’ has no member named ‘b’
Engine.h:14: error: expected type-specifier before ‘Behaviour’
Engine.h:14: error: expected ‘;’ before ‘Behaviour’
In file included from Engine.h:5:
Behaviour.h:11: error: expected ‘)’ before ‘*’ token
Behaviour.h:23: error: ISO C++ forbids declaration of ‘Engine’ with no type
Behaviour.h:23: error: expected ‘;’ before ‘*’ token
Behaviour.h: In member function ‘void Behaviour::work()’:
Behaviour.h:19: error: ‘class Behaviour’ has no member named ‘e’
Engine.h: In constructor ‘Engine::Engine()’:
Engine.h:14: error: no matching function for call to ‘Behaviour::Behaviour(Engine* const)’
Behaviour.h:7: note: candidates are: Behaviour::Behaviour()
Behaviour.h:7: note:                 Behaviour::Behaviour(const Behaviour&)

前方宣言が必要だと思いますが、よくわかりません。チュートリアルを調べていくつかの試行を行っても、問題はまったく解決しません。

4

2 に答える 2

4

インクルードを前方宣言にEngine.h置き換えます。

#include "Behaviour.h"

class Behaviour;

class Engine;内部も同じBehavior.h

循環依存関係があるため、インクルードの代わりに前方宣言を使用する必要があります。

また、ファイル内の実装を分離する必要がありcppます。前方宣言だけでは、 を呼び出すことはできませんthis->b = new Behaviour(this);

また、時間をかけてデザインを再考してください。この種の依存関係は通常、コードの匂いです。

于 2012-05-23T13:57:05.483 に答える
1

循環依存の問題が発生しました。通常、CPP ファイルに Behaviour のメソッドを実装する必要がありますが、ベスト プラクティスではない可能性があります。エンジンは、アプリケーションにおいて非常に重要な抽象概念であると思います。純粋な仮想クラスをインターフェイス定義として記述できます。

例えば:

IEngine.h

class IEngine {
public:
    void work() = 0;
};

IEngine* newEngine();

EngineImpl.h

class EngineImpl : public IEngine {
public:
    void work();
};

EngineImpl.cpp

void EngineImpl::work();
   // do some works
}

IEngine* newEngine() {
    return new EngineImpl();
}

これで、IEngine.h をインクルードするだけで、コードのどこでも IEngine でエンジンを使用できます。また、定義によって Engine シングルトンを実装することもできます。

IEngine.h:

IEngine* sharedEngine();

EngineImpl.cpp

IEngine* sharedEngine() {
    static IEngine *engineInst = 0;
    if (!engineInst)
        engineInst = new EngineImpl();
    return engineInst; 
}
于 2012-05-23T14:19:57.460 に答える