If you cannot modify even the derived classes, it's hard to call GetInfo on them not knowing, that they are of specific type. Maybe you are required to use direct solution:
GradStudent gradStudent;
cout << gradStudent.GetInfo();
Or you can try to check, if a student is of specified derived class, but IMO it's extremely ugly and dangerous (in terms of extending the code):
for (int i = 0; i < 3; i++)
{
GradStudent * gs = dynamic_cast<GradStudent *>(classRoom[i]);
if (gs != nullptr)
cout << gs->GetInfo();
else
{
UndergradStudent * ugs = dynamic_cast<UndergradStudent *>(classRoom[i]);
if (ugs != nullptr)
cout << ugs->GetInfo();
else
cout << classRoom[i]->GetInfo();
}
}
I have to say, that polymorphism is created specifically to handle situations like this and GetInfo not being virtual in base class is serious architectural flaw.
Additionally: if you are playing with pointers, avoid retreiving addresses to local variables. That may be dangerous. Instead, allocate and deallocate the memory manually:
classRoom[0] = new Student;
classRoom[1] = new GradStudent;
classRoom[2] = new UndergradStudent;
// Process data
for (int i = 0; i < 3; i++)
delete classRoom[i];
On the margin: I hate tasks like: Do X without using Y (where Y is specifically designed to solve X).
Edit: (in response to comments)
You asked, how virtual function would resolve the problem. Suppose for a moment, that Student::GetInfo is virtual. Let's analyse the following pieces of code:
Student * student = new Student;
student->GetInfo(); // Student::GetInfo is called
GradStudent * gradStudent = new GradStudent;
gradStudent->GetInfo(); // GradStudent::GetInfo is called
Nothing suprising, for now.
Student * student = new GradStudent;
student->GetInfo();
// if Student::GetInfo is virtual, GradStudent::GetInfo is called here
// if Student::GetInfo is not virtual, Student::GetInfo is called here
Now read carefully. If Student::GetInfo is virtual and is implemented in GradStudent class, GradStudent::GetInfo will be called, despite fact, that it is called on Student variable.
However, if Student::GetInfo is not virtual, in previous case, Student::GetInfo will be called. This is basically how virtual functions work.
In your case, you have an array of Student * variables - you don't exactly know, whether they are Students, GradStudents or UndergradStudents. Since your Student::GetInfo is not virtual, calling this method on these variables will always result in calling Student::GetInfo, regardless of their actual type.
In such case the only solution I can think of is trying to guess, which class actually they are:
Student * student = new UndergradStudent;
Student * s = student; // Ok
GradStudent * gs = dynamic_cast<GradStudent *>(student); // Not true, will return NULL/nullptr
UndergradStudent * ugs = dynamic_cast<UndergradStudent *>(student); // Ok
This way you can return to the original type and call GetInfo of the actual variable type.
Note though, that this is an ugly solution and this kind of problems is solved by virtual functions.
The C++ FAQ is a good place to read further about virtual functions.
getInfoisvirtual-- which it should be, since it's in the base class you cannot change -- this should work. What's the problem exactly?Student'sgetInfo()on yourGradStudentinstance?