0

I've been looking through a lot of old posts and still can't seem to figure out what I'm doing wrong. Would appreciate any help refactoring this into code that will work.

I'm getting an error in my quizquestion.h file stating that object of abstract type "Answer" is not allowed due to Answers::getAnswers being a pure virtual function. I can't figure out how I should go about making the code work. From what I can tell, it looks like I'm overloading the purely virtual function correctly in the Answer class, but this must clearly not be the case. This is what I currently have:

quizquestion.h

#ifndef QuizQuestion_h
#define QuizQuestion_h

#include "answerdata.h"
#include "answer.h"

#include <string>
#include <vector>
#include <iostream>
#include <fstream>

class QuizQuestion {
    public:
        QuizQuestion();
        QuizQuestion(int num);
        
        void getQuestion(std::ostream& outs);
        void getAnswers(std::ostream& outs);
       

        void setQuestion(std::string q);
        void setAnswers();
        int setAnswersMenu();

        void getMenu();
    
    private:
        std::string question;
        Answer answers;
};
#endif

answers.h

#ifndef Answer_h
#define Answer_h

#include "answerdata.h"

#include <vector>

class Answer {
    public:
        Answer * Create(int num);
        virtual void getAnswers(std::ostream& outs) = 0;
};

class TrueOrFalse:public Answer {
    public:
        TrueOrFalse();
        void getAnswers(std::ostream& outs) override;
    
    private:
        AnswerData answers[2];
};

class MultipleChoice:public Answer {
    public:
        MultipleChoice();
        void getAnswers(std::ostream& outs) override;

    private:
        std::vector<AnswerData> answers;
};

class MatchAnswers:public Answer {
    public:
        MatchAnswers();
        void getAnswers(std::ostream& outs) override;

    private:
        std::vector<AnswerData> answers;
};

#endif
Grant
  • 431
  • 3
  • 8
  • 2
    The definition `Answer answers;` is invalid, because it's not possible to define `Answer` objects. For polymorphism you need to use either references or pointers. This should be quite clear in any decent tutorial, class or [book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – Some programmer dude Feb 21 '23 at 07:14
  • Not your immediate problem but `Answer * Create(int num);` is a weird function. How are you expecting to use that? – john Feb 21 '23 at 07:16
  • Read about polymorphism in your favourite C++ book, and forget what you might know about it from other languages. – molbdnilo Feb 21 '23 at 07:18
  • 2
    Strong evidence of faulty design here. Surely `TrueOrFalse` and `MultipleChoice` are types of questions not answers. So these classes should be inheriting from `Question` not `Answer`. – john Feb 21 '23 at 07:18
  • @john for sure! i should rename it to something like QuestionType instead of and rename AnswerData to just Answer – Grant Feb 21 '23 at 07:21
  • @john this is how it's defined ```Answer * Answer::Create(int num) { Answer * p_item(NULL); switch(num) { case 1: p_item = new TrueOrFalse(); break; case 2: p_item = new MultipleChoice(); break; case 3: p_item = new MatchAnswers(); break; default: p_item = NULL; break; } return p_item; }``` – Grant Feb 21 '23 at 07:24
  • 1
    @Grant This is what's known as a factory method. Looks fine except it should be `static`. You don't need an `Answer` object to create another `Answer` object. Making the function `static` expresses this. – john Feb 21 '23 at 07:35
  • @john how would i do that if you don't mind me asking? – Grant Feb 21 '23 at 07:42
  • @Grant do no use NULL, this is C. In C++ there's the nullptr type. – Moia Feb 21 '23 at 08:04
  • As minimal reproducible code you should add cpp files too. There are several mistake there as already stated. Other to not using pointer to manage polymorphism, there's a clear confusion about what an answer is and what a question is – Moia Feb 21 '23 at 08:09
  • @Grant Simple just put `static` in front of the declaration (i.e. in the class, not where you define the method) `class Answer{ public: static Answer * Create(int num); ...` The advantage is you can now call this method without an `Answer` object, like this `Answer* p = Answer::Create(1);` – john Feb 21 '23 at 08:50

0 Answers0