5
votes

I have a class called Masterdocument which contains different Processes. Each Process contains a different number of Questions and possible answers options for each question. The weightage for each answer option is also mentioned in the document. Based on the answer user provides, the master document is consulted and user response is scored. Sample code looks like following.

Class Masterdocument {
vector <MasterProcess>;
}; 
Class MasterProcess1 { 
id = 10;
num of questions = 2;
question1;
answer1option1;
answer1option2;
question1Weightage;

question2;
answer2option1;
answer2option2;
question2weightage;

//constructor
MasterProcess1(){
question1 =1;
answer1option1 =1;
answer1 option2 = 2;
question1weightage = 0.1

question2 =2;
answer2option1 = 1;
answer2option2 = 2;
question2weightage = 0.2;
}
};

Class MasterProcess2 {
id  =11; 
num of questions = 3;
question1;
answer1option1;
answer1option2;
question1Weightage;

question2;
answer2option1;
answer2option2;
answer2option3;
question2weightage;

question3;
answer3option1;
answer3option2;
question3weightage;

//constructor
MasterProcess2(){
question1 =1;
answer1option1 =1;
answer1 option2 = 2;
question1weightage = 0.2

question2 =2;
answer2option1 = 1;
answer2option2 = 2;
answer2option3 = 3;
question2weightage = 0.3;

question3 = 3;
answer3option1 = 1;
answer3option2 = 2;
question3weightage = 0.4
}
};

The MasterDocument and all the MasterProcesses are constants. The values do not change. But the number of questions (and answer options for each question) differs for each process. I can initialize them using the constructor. But how do i add them to the vector in the MasterDocument as all the MasterProcesses have a different name e.g. MasterProcess1, MasterProcess2 and so on. So I cannot have a vector in the MasterDocument.

If i use the same name for every process (call each a MasterProcess), then how would i know which constructor to call for first MasterProcess as it has differet num of questions then second masterProcess.

I can hard code the values in the Master Document as it does not change but how do I initialize the values. I can put all the processes in single MasterDocument and create a huge constructor with all the questions/answers for every process, but that does not look pretty.

I can call each process as MasterProcess and pass the id of the Process in the constructor (like MasterProcess (id)) but how would I dictate that MasterProcess(10) should call the constructor of first class and MasterProcess(11) should call the constructor of second class.

@ Heisenbug

I followed your lead and came up with this code

#include <iostream>
#include <utility>
#include <string>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

class BaseMasterProcess {

protected:

int processID;  
int num_of_Questions;  
double min_Threshold_Score_for_Process;  
double total_Process_Score;  
double overall_Audit_Value;
int question;
pair <int,double> answer;

//define all the variable used in any sub-class 
int question1;
int question2;
int question3;
int question4;
int question5;
double question1_Weightage;
double question2_Weightage;
double question3_Weightage;
double question4_Weightage;
double question5_Weightage;
int passing_Score;
pair <int,double> answer1_Option1;  
pair <int,double> answer1_Option2; 
pair <int,double> answer1_Option3;
pair <int,double> answer2_Option1;  
pair <int,double> answer2_Option2; 
pair <int,double> answer2_Option3;
pair <int,double> answer3_Option1;  
pair <int,double> answer3_Option2; 
pair <int,double> answer3_Option3;
pair <int,double> answer4_Option1;  
pair <int,double> answer4_Option2; 
pair <int,double> answer4_Option3;
pair <int,double> answer5_Option1;  
pair <int,double> answer5_Option2; 
pair <int,double> answer5_Option3;

public:
abstract void Init();
virtual double getQuestionWeightage(int ques) = 0;
virtual double getAnswerScore(int ques, int ans) = 0; 
int getNumQuestions()
{
    return num_of_Questions;
}
int getProcesssID()
{
    return processID;
}
double getMinThresholdScore()
{
    return min_Threshold_Score_for_Process;
}
double overallAuditValue()
{
    return overall_Audit_Value; 
}
};
class ConcreteMasterProcess1 : public BaseMasterProcess
{
public:
    void Init()
    {
processID = 10; 
num_of_Questions = 3;  
passing_Score = 70;  
min_Threshold_Score_for_Process = 0.7; 
overall_Audit_Value = 0.1;

question1 = 1; 
question1_Weightage = 0.3;  
answer1_Option1 = make_pair (1,0.3); 
answer1_Option2 = make_pair (2,0.0);

question2 = 2; 
question2_Weightage = 0.3; 
answer2_Option1 = make_pair (1,0.3); 
answer2_Option2 = make_pair (2,0.0);


question3 = 3;
question3_Weightage = 0.4; 
answer3_Option1 = make_pair (1,0.4); 
answer3_Option2 = make_pair (2,0.0);
}

double getQuestionWeightage(int ques)
{
switch (ques)
{
    case 1:
        return question1_Weightage;
    case 2:
        return question2_Weightage;
    case 3:
        return question3_Weightage;
}
    }
double getAnswerScore(int ques, int ans) 
{
    if (ques == question1 && ans == answer1_Option1.first)
        return answer1_Option1.second;
    else if (ques == question1 && ans == answer1_Option2.first)
        return answer1_Option2.second; 
    else if (ques == question2 && ans == answer2_Option1.first)
        return answer2_Option1.second;
    else if (ques == question2 && ans == answer2_Option2.first)
        return answer2_Option2.second;
    else if (ques == question3 && ans == answer3_Option1.first)
        return answer3_Option1.second;
    else 
        return answer3_Option2.second;

}   
};
class ConcreteMasterProcess2 : public BaseMasterProcess
{
    void Init()
    {
processID = 11; 
num_of_Questions = 4;  
passing_Score = 70;  
min_Threshold_Score_for_Process = 0.75; 
overall_Audit_Value = 0.1;

question1 = 1; 
question1_Weightage = 0.25;  
answer1_Option1 = make_pair (1,0.25); 
answer1_Option2 = make_pair (2,0.0);

question2 = 2; 
question2_Weightage = 0.25; 
answer2_Option1 = make_pair (1,0.25); 
answer2_Option2 = make_pair (2,0.0);
answer2_Option3 = make_pair (3,0.15);

question3 = 3;
question3_Weightage = 0.25; 
answer3_Option1 = make_pair (1,0.25); 
answer3_Option2 = make_pair (2,0.0);

question4 = 4;
question4_Weightage = 0.2; 
answer4_Option1 = make_pair (1,0.2); 
answer4_Option2 = make_pair (2,0.0);

question5 = 5;
question5_Weightage = 0.2; 
answer5_Option1 = make_pair (1,0.2); 
answer5_Option2 = make_pair (2,0.0);
}

double getQuestionWeightage(int ques)
{
switch (ques)
{
    case 1:
        return question1_Weightage;
        break;
    case 2:
        return question2_Weightage;
        break;
    case 3:
        return question3_Weightage;
        break;
    case 4:
        return question4_Weightage;
        break;
}
    }
double getAnswerScore(int ques, int ans) 
{
    if (ques == question1 && ans == answer1_Option1.first)
        return answer1_Option1.second;
    else if (ques == question1 && ans == answer1_Option2.first)
        return answer1_Option2.second; 
    else if (ques == question2 && ans == answer2_Option1.first)
        return answer2_Option1.second;
    else if (ques == question2 && ans == answer2_Option2.first)
        return answer2_Option2.second;
    else if (ques == question2 && ans == answer2_Option3.first)
        return answer2_Option3.second;
    else if (ques == question3 && ans == answer3_Option1.first)
        return answer3_Option1.second;
    else if (ques == question3 && ans == answer3_Option2.first)
        return answer3_Option2.second;
    else if (ques == question4 && ans == answer4_Option1.first)
        return answer4_Option1.second;
    else
        return answer4_Option2.second;

}   
};
class MasterDocument
{
std::vector<BaseMasterProcess*> myProcessList;
void AddProcess(BaseMasterProcess* iProcess)
{
myProcessList.push_back(iProcess);
}
void foo()
{
//myProcessList[...]->Method1(); //do something without knowing which specific concrete    class the process belongs to..
}
};

int main ()
{
BaseMasterProcess bmp; 
ConcreteMasterProcess6 p6;  
MD master_doc;
master_doc.addProcess(bmp); // gives ERROR
    master_doc.addProcess(p6); // gives ERROR
master_doc.foo();

}

It gives me following errors:

Regarding Init() -> ISO C++ forbids declaration of ‘Init’ with no type [-fpermissive] EDIT: changed to void Init() -> RESOLVED Regarding function getQuestionWeightage(int) -> In member function ‘virtual double ConcreteMasterProcess1::getQuestionWeightage(int)’: error: a function-definition is not allowed here before ‘{’ token EDIT: was missing the } at the end of switch -> RESOLVED Regarding main() -> expected ‘}’ at end of input expected unqualified-id at end of input EDIT: has extra } in the mian() -> RESOLVED

How do I resolve the errors shown in main(). All I want to do is create the MasterDocument and have the two Concrete Processes in the myProcssList ???

2

2 Answers

1
votes

Another option using shared_ptr is as follows.

struct Answer {
int whatever;
}

struct Process {
int whatever;
std::vector<std::shared_ptr<Answer> > answers;
};

struct Document {
Document();
std::vector<std::shared_ptr<Process> > processes;
};
int main (){
Document::Document()
{
// Make some processes
for (int i = 0; i < 5; i++) {
std::shared_ptr<Process> foo = std::shared_ptr<Process>();
foo->whatever = i;
processes.push_back(foo);
}
}

}

1
votes

Use a Structure like this. Break it down

MasterDocument{ 
vector <Process> 
... 
}; 
Process{ 
vector<Question>; 
... 
}; 
Question{ 
vector<Answer>: 
... 
}; 
Answer{ 
map<int answer, int score>;  
};