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

正如 dutt 所说,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 回答