I need to create an MVC architecture, where both the View and the Controller classes have already been written as templates as follows:
template<class Model, class View>
class Controller { /* Implement Controller */ };
template<class Model, class Controller>
class View { /* Implement View */ };
I also have a model class:
class Model { /* Implement Model */ };
I have no control over how the Model, View, and Controller classes have been created. Now, how do I instantiate the controller, or the view?
To better explain the situation, if I want to create a Controller using the View and Model classes above (I am NOT allowed to use any other classes), I get:
NOTE: Invalid C++ code follows
Controller< Model, View< Model, // ad infinitum
whereas the following is also invalid:
NOTE: Invalid C++ code follows
Controller< Model, View< Model, Controller > > c;
This is a possible implementation
template<typename View, typename Model>
struct Controller {
View *view;
Model *model;
Controller() : view(0), model(0) {}
void setUp(View *v, Model *m) {
view = v;
model = m;
}
virtual void change() = 0;
};
template<typename Controller, typename Model>
struct View {
Controller *controller;
Model *model;
View() : controller(0), model(0) {}
void setUp(Controller *c, Model *m) {
controller = &c;
model = &m;
}
virtual void display() = 0;
};
To do the instantiation the trick is deriving a class from a template that has a forward declared class as parameter:
struct MyModel {
int x;
MyModel(int x) : x(x) {}
};
struct MyController;
struct MyView : View<MyController, MyModel>
{
void display() { std::cout << model->x << std::endl; }
};
struct MyController : Controller<MyView, MyModel>
{
void change() { model->x = 44; }
};
After that you can create instances and set them up
int main(int argc, const char *argv[]) {
MyModel m(42);
MyView v;
MyController c;
v.setUp(&c, &m); c.setUp(&v, &m);
v.display();
c.change();
v.display();
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With