Let's say I'm developing a grocery list manager. I have a window with a GroceryListDisplay
, which is a control that displays the items that are on the grocery list. The grocery data is stored by the Model component of the program, in the GroceryStorage
class.
To load a saved file into my program, the Model component of my program has to be repopulated with data that was imported from the file. The View component will need to be notified of this new data, otherwise the GUI won't be updated and the user can't see the imported data.
Here's the concept I came up with to facilitate this.
/* A View class that represents a GUI control that displays the grocery list */
class GroceryListDisplay {
public:
void repopulateFromModel(GroceryStorage* gs) {
this->gs = gs;
/* Delete every list entry that was loaded into GUI */
this->clearList();
/* Import grocery list from the Model */
void (*itemAdder)(std::string) = addItemToList;
this->gs->sendGroceryItemsToGUI(addItemToList);
}
void addItemToList(std::string);
void clearList();
private:
GroceryStorage* gs;
}
/* A Model class that stores the grocery list */
class GroceryStorage {
public:
void sendGroceryItemsToGUI(void (*itemAdder)(std::string)) {
/* Sends all stored items to the GUI */
for (int i = 0; i < (int)this->groceryItems.size(); ++i)
itemAdder(this->groceryItems[i]);
}
private:
std::vector<std::string> groceryItems;
}
When the user instructs the GUI to import a certain file, the View will call a function in the Model that loads data from that given file. Then, the repopulateFromModel
function is called to get the GUI up-to-date.
I'm going through the trouble of using a function pointer for the callback in GroceryStorage::sendGroceryItemsToGUI
because otherwise the Model would have to know which function in the View it should call, which would be a violation of the Model/View principle.
There's one big issue with this block of code. If I use this concept in a real life situation, I get a compiler error that says something similar to
error: argument of type ‘void (GroceryListDisplay::)(std::string)’ does not match ‘void (*)(std::string)’
Is the compiler asking me to hardcode the name of the class from which the function pointer originates? I can't do that, because this would imply that the Model knows which View class is responsible for handling the callback which, again, would be a Model/View violation.
Did I misunderstand how function pointers work?