What is wrong with the following code with respect to inheritance? Getting no matching function for call to ‘student::student()’
error.
class student {
private:
string firstname;
string lastname;
public:
student(string fname, string lname) {
firstname = fname;
lastname = lname;
}
string getname() { return firstname lastname; }
void setfirstname(string fname) { this->firstname = fname; }
};
class undergraduate : public student {
private:
double gpa;
student* stu;
public:
undergraduate(string firstname, string lastname, double gpa) {
stu = new student(firstname, lastname);
this->gpa = gpa;
}
};
int main() {
undergraduate stu1("Sam", "Singh", 4.0);
stu1.setfirstname("temp");
cout << stu1.getname();
}
Please point out the mistake and help me in rectifying it. Thanks!
CodePudding user response:
It looks like you might be a Python programmer, so here is your code, re-written in that langage
class student:
def __init__(self, fname, lname):
self.firstname = fname;
self.lastname = lname;
@property
def name(self):
return self.firstname self.lastname
class undergraduate(student):
def __init__(self, fname, lname, gpa):
super().__init__(fname, lname)
self.gpa = gpa
stu1 = undergraduate("Sam", "Singh", 4.0);
stu1.firstname = "temp";
print(stu1.name)
The first thing to notice is that the undergraduate
does not contain a student
member. Since it inherits from student
(is a) there is no need for a member in undergraduate
. It's the same for the C class.
However, in the Python code, the undergraduate
class calls the student
ctor in the body of the undergraduate
ctor. That's different from how it works in C . That language uses "initializer lists". These are used to not only call parent ctors but also initialize member variables.
class student {
private: // You may want to change to protected so child classes can access
string firstname;
string lastname;
public:
student(string fname, string lname) {
firstname = fname;
lastname = lname;
}
string getname() { return firstname lastname; }
void setfirstname(string fname) { this->firstname = fname; }
};
class undergraduate : public student {
private:
double gpa;
public:
undergraduate(string firstname, string lastname, double gpa) :
student(firstname, lastname), // Call parent ctor
gpa(gpa) // Initialize this->gpa to gpa parameter
{
// The initializer list has taken care of everything so there's nothing here
// But additional code could be added if needed.
}
};
int main() {
undergraduate stu1("Sam", "Singh", 4.0);
stu1.setfirstname("temp");
cout << stu1.getname();
}
If you are confused about how inheritance works, I strongly recommend you find a good book or tutorial. Answers on SO cannot go into enough detail to fully explain the concepts.
The Definitive C Book Guide and List
Constructors and member initializer lists
RE the original error in the code: the compiler is looking for a default ctor (no parameters) for student
but you do not provide one. See: When do we need to have a default constructor?
CodePudding user response:
The undergraduate
is a student
. Therefore, the construction of undergraduate
needs to first construct the parent class student
.
Since you have not provided, how to construct the parent student
in
undergraduate(string firstname, string lastname, double gpa)
{
stu = new student(firstname, lastname);
this->gpa = gpa;
}
before it comes to the constructor body, the compiler will try to do it for you by calling the default constructor of student
. Since the student has parameterized constructor student(string fname, string lname)
, the compiler will not generate one for you and end up not having a default constructor for student. This leads to the error.
Secondly, you do not require the pointer to the parent, unless you have any other special requirements.
Therefore, you have two different options to solve the issue.
- Provide the default constructor for
student
. - Or initialize the
student
in the child constructor (undergraduate
), removing the redundant pointer tostudent
.
Also use the constructor member initializer list for initializing the member of the class:
undergraduate(string firstname, string lastname, double gpa)
: student{ std::move(firstname), std::move(lastname)}
, gpa{ gpa}
{}