stl stack fun

Started by
11 comments, last by Zahlman 17 years, 6 months ago
I'm creating an application that runs as a stack: exit->menu->game. every part of a stack is a separate function. since STL stack cannot use function pointers, i wrap it like that:

struct StateStruct
{
   typedef void (*StatePointer)();
};

It run fine when the Exit(), Menu() and Game() functions were global, but I decided to try to change it to oop (and here came the uglies) I have class App, containing basically whole my program,

int main(int argc, char *argv[])
{
App *MyDemo = new App;
MyDemo->MainLoop();
delete MyDemo;
return 0;
}

void App::MainLoop() 
{
while (!stateStack.empty())
{
stateStack.top().StatePointer();
}
}


I've created a method Exit() of the App

void App::Exit() 
{
cout << "I am exiting game." << endl;
stateStack.pop();
}

and now in App::Init(), I try to use

StateStruct state;
state.StatePointer = Exit; // <-- DevCPP throws out error here
// state.StatePointer =&App::Exit; gives same error as the line above
stateStack.push(state);


the error is "invalid use of `StateStruct::StatePointer'" oh yeah,

stack<StateStruct> stateStack; // application's state stack

is a private member variable of class App. I _really_ have no idea what to do now. Any help will be appreciated.
If only noobs were boobs... the world would be a better place.
Advertisement
Quote:Original post by EliteWarriorManTis
since STL stack cannot use function pointers, i wrap it like that:


Says who?

#include <iostream>#include <stack>void foo() { std::cout << "hi" << std::endl; }int main(){    std::stack<void (*)()> s;    s.push(&foo);    s.top()();    s.pop();}


Quote:the error is "invalid use of `StateStruct::StatePointer'"


A pointer to a (non-static) member function is not the same thing as a pointer to a non-member function. You cannot use one where the other is expected.

Furthermore (and that's the error you're getting), StateStruct::StatePointer is a type not a variable (see that typedef keyword), so trying to assign it a value is meaningless.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Maybe this is just an intellectual exercise for you, in which case I'll shut up. But if you're trying to write practical code...well, you're using C++ as if it were C or ML. Object-oriented languages should be passing around objects, not functions. Make some State class with a virtual method you can override, then derive your Exit, Menu, and Game classes from that base. The syntax is much less ugly.
Quote:Original post by drakostar
Object-oriented languages should be passing around objects, not functions. Make some State class with a virtual method you can override, then derive your Exit, Menu, and Game classes from that base.


You can consider a function pointer as an object that only implements the function call operator. A virtual function call is more or less the same thing as using a function pointer anyway...
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Quote:Original post by drakostar
Maybe this is just an intellectual exercise for you, in which case I'll shut up. But if you're trying to write practical code...well, you're using C++ as if it were C or ML. Object-oriented languages should be passing around objects, not functions. Make some State class with a virtual method you can override, then derive your Exit, Menu, and Game classes from that base. The syntax is much less ugly.
You gave the wrong reasons. A good reason to use objects in C++ is that they can contain state, whereas C++'s functions can't (no closures). But that of course doesn't apply if you're 100% sure you don't need state. Using function pointers isn't really that ugly, especially if you use typedef for the function pointer type.
And by "state" I also mean non-mutable state like a parameter to a function that is fixed on the object creation site. Such state is very often useful..
Thanks for all the replies. No, this is not a intellectual exercize, but like I stated: I wrote that I'm changing this from C-like functions to OOP, and I have problems with it, cause quite frankly I don't have that much experience with C++ specific solutions. Can anybody give me pseudocode/code how it would look with state class? I'd like to try that approach, but I've no idea where to start.

TIA
If only noobs were boobs... the world would be a better place.
Quote:Original post by EliteWarriorManTis
Thanks for all the replies. No, this is not a intellectual exercize, but like I stated: I wrote that I'm changing this from C-like functions to OOP, and I have problems with it, cause quite frankly I don't have that much experience with C++ specific solutions. Can anybody give me pseudocode/code how it would look with state class? I'd like to try that approach, but I've no idea where to start.

class Function{public:  virtual void execute() const = 0;};class ExitFunction: public Function{public:  ExitFunction(int status = 0)  : m_status(status)  { }  void execute() const  { exit(m_status); }private:  int m_status;};typedef std::stack<Function*> StateStack;int main(int, char*[]){  StateStack stateStack;  stateStack.push(new ExitFunction(-1));  stateStack.top()->execute();}

Stephen M. Webb
Professional Free Software Developer

This is fine and all, but I still don't know how to insert this stack into my class App so that the functions like ExitFunction can access other members of the class, and be stacked at the same time. Note that I will have to use class MainLoopFunction (or something along the lines), and it'll have to have access to all the application stuff.

newb, eh?
If only noobs were boobs... the world would be a better place.
Quote:Original post by EliteWarriorManTis
This is fine and all, but I still don't know how to insert this stack into my class App so that the functions like ExitFunction can access other members of the class, and be stacked at the same time. Note that I will have to use class MainLoopFunction (or something along the lines), and it'll have to have access to all the application stuff.


One of the hallmarks of poor object-oriented design is to have classes represent functions rather than things. An "Application" is probably a good choice for a class. A MainLoopFunction is probably not. It might, however, be a good candidate for a member function of an Application.

That said, it sounds like what you might want to do is either have the Application object be globally accessible from you stacked commands, or else pass a reference to the application to functions of your commands that need to ask the application object to do something.

SO, the App would have_a command stack, and commands would ask the application to perform some functions.

Since there is generally a single application object per, uh, application, many frameworks provide a global pointer to the application object.

Is this getting close to addressing your question?

Stephen M. Webb
Professional Free Software Developer

This topic is closed to new replies.

Advertisement