0

私は C++ の初心者で、複数の名前空間を同時に処理する方法を理解するのに苦労しています。私の MVC アプリケーションでは、ビューはアクションを転送するためにコントローラーへの参照を必要としますが、コントローラーは何かを表示するためにビューへの参照を必要とします。

アプリケーションからほとんどすべてを削除しましたが、名前空間と宣言されていない識別子に関する多くのコンパイル エラーがまだ残っています。これは削除されたコードです:

 #ifndef _geometria
#define _geometria

namespace core_stuff {

/*this namespace contains Model and Controller */

class Model {

public:
    Model();
    //void doSomething();

};

class Controller {

public:
    Controller();
    void setView(ui_stuff::View v);

};

}

namespace ui_stuff {

/*this namespace contains View and other UI classes libraries, not included here because I am semplifying the whole stuff */

class View {

public:
    View();
    void setController(core::Controller c);

};

}


#endif

これが実装です:

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


//implementation of core_stuff namespace  

core_stuff::Model::Model() { }

core_stuff::Controller::Controller() { }

void core_stuff::Controller::setView(ui_stuff::View v) {
//do some kind of operation in my view
}


//implementation of ui_stuff namespace*/

ui_stuff::View::View() { /* */ }

void ui_stuff::View::setController(core_stuff::Controller c) {
//do some kind of operation on the controller
}



/* main */
int main (int nArgs, char* args[]) {
core_stuff::Model m;
core_stuff::Controller c;
ui_stuff::View v;
v.setController(c);
c.setView(v);
}

コンパイル エラーの非常に長いリストの最初のエラーには、

void setView(ui_stuff::View v);

ヘッダー ファイルの次の行で、ui_stuff 名前空間にアクセスできません:

行 (20): エラー C2653: 'ui_stuff' はクラスまたは名前空間の名前ではありません

これを修正するにはどうすればよいですか?

4

2 に答える 2

3

ui_stuff::View使用する前に前方宣言が必要です

namespace ui_stuff
{
    class View; // a forward declaration of ui_stuff::View
}

namespace core_stuff
{
   class Controller {
       void setView(ui_stuff::View& v);
   };
}

namespace ui_stuff
{
   class View
   {
   public:
        void setController(core_stuff::Controller& c);
   };
}

私も参考にさせてもらいました。それはおそらくあなたが望むものです(ビューのコピーではありません)。

宣言を変更した理由を簡単に説明します。値渡しViewを のメソッドに渡し、値Controller 渡しをに渡すことはできません。これは、値渡しの場合、渡すオブジェクト全体を定義する必要があるためです。コントローラーはビューの完全な定義に依存するため、ビューの前にコントローラーを完全に定義することはできません。ただし、同じ理由でコントローラーの前にビューを定義することはできません。したがって、「参照渡し」ビットです。ControllerView

両方のクラスが宣言されたら、それらが相互に作用する方法を定義できます。

于 2013-02-05T16:25:24.467 に答える
1

言われたとおり、C++ は順番に解析されます。これは、C++ コードの各行で、コンパイラはそれまでに定義されたものだけを認識していることを意味します。

問題を解決するには、コアの前に ui_stuff を移動する必要がありますが、クラス スタブも確認する必要があります。例:

namespace ui_stuff {
class View; //This class exists but I will not define it yet.
}

問題は、ビューとは何かを正確に知らないため、ビューをコピーとして渡すことができないことです。ただし、ポインターまたは参照として渡すことができます(ポインターも参照もデータのサイズを知る必要がないため)。

したがって、コードでは、これを行う代わりに:

class Controller {

public:
    Controller();
    void setView(ui_stuff::View v);

};

次のようにします。

class Controller {

public:
    Controller();
    void setView(ui_stuff::View& v);

};

&は、新しいコピーではなく、既存のビューの参照を期待していることを示しています。

于 2013-02-05T16:29:48.147 に答える