Friday, February 11, 2011

How should i randomly call class member methods ?

Hi there.

I am writing a small "quiz program". It looks similar to this:

#include <cstdlib>
#include <iostream>
#include <time.h>

using namespace std;

using std::cout;

class cQuestion
{
  private:
    static short goodAnswers[20][2];

  public:
    static void checkAnswer(int questNumber)
    { 
      /* checking input, checking if answer is bad or good */
      /* putting the answer to cQuiz::answArr */
    };

    static void question1(void) { cout << "this is question 1"; };
    static void question2(void) { cout << "this is question 2"; };
    static void question3(void) { cout << "this is question 3"; };
    static void question4(void) { cout << "this is question 4"; };
    static void question5(void) { cout << "this is question 5"; };
    /*and so on to question 20*/
};

short cQuestion::goodAnswers[20][2] = {0,0};

class cQuiz
{
  private:
    static short questArr[5];
    static short answArr[5];

  public:
    void drawRandom(void)
    {
      srand ( time(NULL) );

      for (int i = 0; i < 5; i++ )
        questArr[i] = rand() % 20 + 1;
    };

    void askQuestions(void)
    {
      for (int i = 0; i < 5; i++ )
      {
        /* call questions by question number from questArr */
        /* HOW SHOULD I CALL CERTAIN cQuestion CLASS MEMBER ?? */
        cQuestion::checkAnswer(questArr[i]);
      }
    };
};

short cQuiz::questArr[5] = {0};
short cQuiz::answArr[5] = {0};

int main(int argc, char *argv[])
{
  cQuiz quiz;
  quiz.drawRandom();
  quiz.askQuestions();

  system("PAUSE");
  return EXIT_SUCCESS;
}

I am wondering, how can (or should) I call class cQuestion member methods ? I was thinking about using an array of pointers to these members (cQuestion::question1, cQuestion::question2, and so on) or overloading subscript operator[].

I am not sure if either way is good or bad. Should i consider different solution or somehow use both together? Or am I completely missing the point?

  • Why is each question in its own method? Why not make an array of strings to store the questions?

    From eduffy
  • This is not good design. Having to add a new method for each question means that you have to recompile each time you add aquestion to the quiz. And as you have found out, it is hard to call those functions randomly. A re-design is in order here.

    dygi : Mhm.. I've done it this way, because each `cQuestion::question();` member "builds question", calling some other member methods, from other classes, putting them together on the screen (text, an pseudographic image, and some more).
    anon : That's not a good reason. Making question a class containing the various compinents might be better bet. You then build instances of this class using different components, and the quiz becomes a collection of the question instances.
    dygi : Technically i understand what you say. I know what an instance, composition and collection is but .. Can i ask You for a simple example ? I don't see how can i build instances of the class using **different** components.
    anon : If your questions are all the same form, say some text a graphic and an answer, then the class simply contains instances (say two strings and an image object). If they have variable numbers of components, then you need a vector (or similar container) of pointers to content objects, and the content objects need to instances of classes in a class heirarchy.
    dygi : Ok, so i need a small amount of redesigning to simplify my problem. Thank You very much.
    From anon
  • How about something like this?

    string[] questions = {"Q1","Q2","Q3"};
    void question(int i)
    {
        cout << questions[i];
    }
    
    From Amarghosh
  • Further to the OOP post above, how about:

    class Question { // Make this a C++ interface
      public:
        Question(string q, string a)
          : QuestionText(q), Answer(a)
        {}
        string QuestionText;
        string Answer;    
    } 
    

    Then instantiate these using a factory or just in your initialisation function:

      q1 = Question("What is the secret of life", "DNA");
      q2 = Question("What is the answer to the great question", "42");
    

    You should probably put these in a vector, rather than in local or global variables.

    Martin York : The question is "What is the the answer to life the universe and everything?". Even google has the answer: http://www.google.com/search?hl=en&client=firefox-a&rls=org.mozilla%3Aen-US%3Aofficial&hs=Whw&q=the+answer+to+life+the+universe+and+everything&aq=f&oq=&aqi=g-c1g4g-c2g1g-c1g1
    Alex Brown : Opinion is still divided as to what the actual question is.
    From Alex Brown
  • Apart from all the OOP dilemmas, maintain an array of function pointers to your member functions and randomly select one of them.

    dygi : The fastest and working approach in this situation, thanks. Didn't know about that: `Firstly, you can't use a member function to point to a static member function. You have to use a normal function pointer for that.`
    From Jacob

0 comments:

Post a Comment