Reputation: 2833
// Shadowing
#include <iostream>
using namespace std;
const int MNAME = 30;
const int M = 13;
class Person { // Base Class
char person[MNAME+1];
public:
void set(const char* n);
void display(ostream&) const;
protected:
const char* name() const;
};
void Person::set(const char* n) {
strncpy(person, n, MNAME);
person[MNAME] = '\0';
}
void Person::display(ostream& os) const {
os << person << ' ';
}
const char* Person::name() const { return person; }
class Student : public Person { // Derived
int no;
char grade[M+1];
public:
Student();
Student(int, const char*);
void display(ostream&) const;
};
Student::Student() {
no = 0;
grade[0] = '\0';
}
Student::Student(int n, const char* g) {
// see p.61 for validation logic
no = n;
strcpy(grade, g);
}
void Student::display(ostream& os) const {
os << name() << ' '
<< no << << ' ' << grade << endl;
}
int main() {
Person person;
Student student(975, "ABBAD");
student.set("Harry");
student.display(cout); // Harry 975 ABBAD
person.set("Jane Doe");
person.display(cout); // Jane Doe
}
The first call to display() (on student) calls the Student version of display(). The second call to display() (on person) calls the Person version of display(). The derived version of display() shadows the base version on the student object. The base version executes on the person object.
I don't understand what shadowing is then. I realize that both classes have the same display function defined, and obviously if you call student.display and person.display its going to call them accordingly. So what does this mean:
The derived version of display() shadows the base version on the student object. The base version executes on the person object.
I don't understand shadowing.
source: https://scs.senecac.on.ca/~btp200/pages/content/dfunc.html Inheritance - Functions of a derived class
Upvotes: 2
Views: 6069
Reputation: 14730
Try this little experiment. Define the following function:
void person_display(Person &p){
p.display(cout);
}
Then have main
call it on person
and student
.
int main(){
// [...]
person_display(person);
person_display(student);
}
You will see that in both cases, the method Person::display
will be called. The shadowing is a phenomenom happening because of the redefinition in a class of a method of its ancestor class. It shadows the previous definition, as long as the instance is considered as the subclass, but as soon as it is seen as the ancestor, the shadowing disappears.
This is in contrast with a virtual
method, where the method called is always the one defined in the real instance class, ie. in the experiment described above, you would see the Student
method being called, even though it is seen as a simple Person
.
Upvotes: 0
Reputation: 8072
It means that you're most likely missing a virtual
.
E.g., your Person class should probably look like:
class Person { // Base Class
char person[MNAME+1];
public:
void set(const char* n);
virtual void display(ostream&) const;
protected:
const char* name() const;
};
Right now, if you have the following code:
Person* student = new Student(975, "ABBAD")
student->set("Harry");
student->display(cout);
Your output will be "Harry " instead of "Harry 975 ABBAD\n". As icepack says, the reason you're getting the message is because the display method in the Student class "shadows" the display method in the Person class, and because you have not declared that method virtual, the compiler assumes that the shadowing is accidental. If it's not accidental, then you should declare that method virtual.
Upvotes: 1
Reputation: 18358
Your Student
class inherits from Person
. That means, among other things, that Student
objects consist from all the internals defined in Student
and from all the internals defined in Person
- for this matter Student
can be seen as containing the Person
. This means that Student
object contains both versions of display
method - one from the the base class and one from the derived. Shadowing means that when invoking the display
from the derived object, it will call the derived class version, and the base class version is "shadowed" by it and not called. You can call the shadowed version from within Student
by explicitly specifying it with base class prefix: Person::display
. In general, the function that will be called is the one closest in scope - for Derived
objects it's the scope of Derived
and functions residing in outer scopes (such as base) are shadowed away.
Upvotes: 2