c++命名空间/标识符问题

c++ namespace / identifier issues

本文关键字:问题 标识符 命名空间 c++      更新时间:2023-10-16

我是C++的新手,在理解如何同时处理多个命名空间时遇到了困难。在我的MVC应用程序中,视图需要对控制器的引用来转发操作,而控制器需要对视图的引用来显示某些内容。

我已经从我的应用程序中删除了几乎所有的内容,并且我仍然有很多关于nomespace和未声明标识符的编译错误。这是剥离的代码:

 #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"不是类或命名空间的名称

我该怎么解决这个问题?

在使用它之前,您需要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的方法,也不能按值向View传递Controller。这是因为,当您按值传递时,必须定义您传递的整个对象。不能在视图之前完全定义控制器,因为控制器取决于视图的完整定义。但由于同样的原因,您不能在控制器之前定义视图,因此使用了"按引用传递"位。

一旦声明了这两个类,就可以定义它们相互交互的方式。

作为dutt saide,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);
};

&表示您期望的是对现有视图的引用,而不是新副本。