Я новичок в C ++, и я сталкиваюсь с трудностями в понимании того, как обрабатывать более 1 пространства имен одновременно. В моем приложении 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» не является именем класса или пространства имен
Как я должен это исправить?
Вам понадобится предварительная декларация для 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
а также передать Controller
по значению для View
, Это потому, что когда вы передаете по значению, весь объект, который вы передаете, должен быть определен. Вы не можете полностью определить контроллер перед представлением, потому что контроллер зависит от полного определения представления. Но вы не можете определить представление перед контроллером по той же причине, отсюда и бит «передача по ссылке».
Как только оба класса объявлены, вы можете определить, как они взаимодействуют друг с другом.
Как говорит Датт, C ++ анализируется по порядку. Это означает, что в каждой строке кода C ++ компилятор знает только то, что было определено до сих пор.
Чтобы решить вашу проблему, вы должны просто переместить ui_stuff перед основным материалом, но вы также должны взглянуть на заглушку класса. Пример:
namespace ui_stuff {
class View; //This class exists but I will not define it yet.
}
Проблема в том, что вы можете не Передайте View как копию, потому что вы точно не знаете, что такое View. Но вы можете передать как указатель или же ссылка (потому что ни указатель, ни ссылка не должны знать размер данных).
Итак, в вашем коде вместо этого:
class Controller {
public:
Controller();
void setView(ui_stuff::View v);
};
Вы бы сделали это:
class Controller {
public:
Controller();
void setView(ui_stuff::View& v);
};
&
означает, что вы ожидаете ссылку на уже существующее представление вместо новой копии.