tags:

views:

143

answers:

5

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?

A: 

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

eduffy
+4  A: 

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.

anon
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).
dygi
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.
anon
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.
dygi
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.
anon
Ok, so i need a small amount of redesigning to simplify my problem. Thank You very much.
dygi
A: 

How about something like this?

string[] questions = {"Q1","Q2","Q3"};
void question(int i)
{
    cout << questions[i];
}
Amarghosh
+2  A: 

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.

Alex Brown
Martin York
Opinion is still divided as to what the actual question is.
Alex Brown
A: 

Apart from all the OOP dilemmas, maintain an array of function pointers to your member functions and randomly select one of them.

Jacob
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.`
dygi