I was tryiing to inherit a comstructor from base class to the a derived class which was derived from another derived class of the base class. but it says " no deafault constructor exists for class Waiverstudents " after inheriting the base class constructor.
class Student
{
private:
string StudentName, StudentID, CGPA , UpcomingSemester , UpcomingSemesterCredits;
public:
Student (string a, string b, string c , string d, string e)
{
StudentName= a;
StudentID=b;
CGPA=c;
UpcomingSemester=d;
UpcomingSemesterCredits=e;
}
string DisplayStudent()
{
cout<<StudentName<<endl<<StudentID<<endl<< CGPA <<endl<< UpcomingSemester <<endl<< UpcomingSemesterCredits;
}
};
class ScholarshipStudents: virtual public Student
{
private:
float ScholarshipPercent = 0.3;
float tution_fee;
public:
ScholarshipStudents(string a, string b, string c , string d, string e) : Student(a,b,c,d,e)
{}
float TutionFee(int a)
{
tution_fee=(a*ScholarshipPercent);
return tution_fee;
}
string DisplayScholarshipStudent()
{
DisplayStudent();
cout<<tution_fee;
}
};
class WaiverStudents: virtual public Student
{
private:
float Waiverpercent = 0.15;
float tution_fee;
public:
WaiverStudents (string a, string b, string c , string d, string e) : Student(a,b,c,d,e)
{}
float WaiverTuitionFee(int a )
{
tution_fee =(a*Waiverpercent);
}
string DisplayWaiverStudent()
{
DisplayStudent();
cout<<tution_fee;
}
};
class SpecialStudents : public WaiverStudents , public ScholarshipStudents
{
public:
SpecialStudents(string a, string b, string c , string d, string e): Student(a,b,c,d,e)
{} //in this line it shows error. " no deafault constructor exists for class Waiverstudents "
string DisplaySpecialStudent()
{
DisplayStudent();
}
};
I tried This
SpecialStudents(string a, string b, string c , string d, string e): ScholarshipStudents(a,b,c,d,e):WaiverStudents(a,b,c,d,e)
same thing happened.
please help me. to overcome the situation. why the I cant inherit the the constructor
There are several problems in your code so I'm going to provide a quick solution to the immediate problem in your question. The problem that you are experiencing is because of the way that virtual inheritance works. In virtual inheritance the most derived type (
SpecialStudentsin your code) calls the constructor in the base class (Studentin your code). It must also call a constructor in each of the other classes it derives from (ScholarshipStudentsandWaiverStudents). Since you are only invoking the constructor ofSpecialStudentsthe compiler will implicitly try to invoke the default constructor of all other classes it inherits from and since those constructors do not exist you receive an error.To fix this you have two options. The first is to explicitly invoke the constructors of each of the classes
SpecialStudentsand the second provide a default constructor inScholarshipStudentsandWaiverStudents. The most optimal choice in this case it to provide default constructors in those classes but make themprotectedto prevent them from being called except during the creation of a derived type.And finally your most derived type only needs to explicitly call the constructor in
StudentPlease be aware that there are several other problems in your code and the use of virtual inheritance to approach this problem is an incredibly terrible idea. What happens if you add another tuition based fee adjustment? How many different class types will you need to to add to support it. what happens if several more adjustments are added? Now thing about what happens if an existing fee is added or removed from an existing student. Not only will you have to recreate the student but every other reference to that original instance of
Studentwill need to be informed of the change - otherwise they are now working with stale student data.A rule of thumb in object oriented development is to prefer composition and aggregation over inheritance and in your case a very compelling example of why. You have created multiple derived types to support something that would be much better served as a simple attribute of student - i.e. a list of fee adjustments that can be applied to their tuition. This way when new fees and adjustments need to be applied to the student those pieces of data can be managed in a more focused and cohesive manner.
One way to do this is to start by creating a type that represents a fee adjustment. Something that has a name along with the adjustment itself. We're also going to stop using
using namespace stdbecause it's an incredibly bad practice. Instead we'll scope in the names we need viastd::.Now of course you'll need to update the
Studentclass to manage a list of adjustments as well as the overall tuition the student needs to pay. We can do that by adding a couple of new members toStudentlike so.Now that we have something to track our tuition and keep our list of adjustments in a vector, we'll also want to update the constructor so that it takes the initial tuition fee. We'll also want to update the names of the parameters the constructor takes for clarity.
We'll also want to add some new functionality so that we can add a fee adjustment for the student. I'll leave modifying and removing the fees up to you as an exercise.
And finally we'll want to update
DisplayStudentso that it includes a list of fees along with the adjusted tuition. To do this we we can just iterate over the list of fees and while displaying them create a total amount to be subtracted from the students tuition.Now to do some quick validation we'll just create an instance, add some fee adjustments, and display the student.
Which gives us the following output: