Inheritance/Polymorphism  «Prev  Next»
Lesson 8 A derived class
Objective Example of typing conversion and visibility

Typing Conversion Example in C++

Write input member functions for the student and grad_student classes that read input data for each data member of the respective classes.
The print() member function is implemented in both the student and grad_student classes as follows:
void student::print() const
{
   cout << "\n" << name << " , " << student_id
     << " , " << y << " , " << gpa << endl;
}

void grad_student::print() const
{
   student::print(); //base class info printed
   cout << dept << " , " << s << '\n'
     << thesis << endl;
}

For grad_student::print() to invoke the student::print() function, the scope resolved identifier student::print() must be used. Otherwise, there will be an infinite loop. To see which versions of these functions get called, and to demonstrate some of the conversion relationships between base and publicly derived classes, we write a simple test program:

C++ Test pointer components

The diagram below details the elements of the C++ Test Pointer.
C++ Test pointer
1) C++ Code:
// Test pointer conversion rules.

#include "student.h"  // Include relevant declarations

int main()
{
    student s("Mae Pohl", 100, 3.425, fresh),
           *ps = &s;
    grad_student gs("Morris Pohl", 200, 3.2564, grad, 
                     ta, "Pharmacy",
                     "Retail Pharmacies"), *pgs;

    ps -> print();     // student::print
    ps = pgs = &gs;
    ps -> print();     // student::print
    pgs -> print();    // grad_student::print
}



student s("Mae Pohl", 100, 3.425, fresh), *ps = &s;
grad_student  gs(&Morris Pohl", 200, 3.2564, grad, ta, "Pharmacy",
"Retail Pharmacies"), *pgs;

2) Relevant Text:
  • Description: Test pointer conversion rules.
  • File Inclusion: #include "student.h" indicates external header file declarations.
  • Key Commented Lines:
    • ps -> print(); // student::print
    • ps = pgs = &gs;
    • ps -> print(); // student::print
    • pgs -> print(); // grad_student::print
  1. This function declares both objects and pointers to them. The conversion rule is that a pointer to a publicly derived class may be converted implicitly to a pointer to its base class. In our example, the pointer variable ps can point at objects of both classes, but the pointer variable pgs can point only at objects of type grad_student. We wish to study how different pointer assignments affect the invocation of a version of print().
  2. This invokes student::print(). It is pointing at the object "s" of type student.
  3. This multiple assignment statement has both pointers pointing at an object of type grad_student. The assignment to ps involves an implicit conversion.
  4. This again invokes student::print(). The fact that this pointer is pointing at a grad_student object "gs" is not relevant.
  5. This invokes grad_student::print(). The variable pgs is of type pointer to grad_student and, when invoked with an object of this type, selects a member function from this class.

Objects, Abstraction, Data Structures

C++ Program Dissection

The C++ code demonstrates the principles of pointer conversion in C++ when dealing with inheritance.
Let's break it down, along with some corrections and explanations for clarity.
Key Points of the C++ Code:
  1. Objects and Pointers:
    • student s is a base class object.
    • grad_student gs is a derived class object (assuming grad_student publicly inherits from student).
    • ps is a pointer to the base class student.
    • pgs is a pointer to the derived class grad_student.
  2. Implicit Pointer Conversion:
    • A pointer to a derived class object can be implicitly converted to a pointer to its base class. This happens in the line:
    • ps = pgs = &gs;
              
      Here, pgs (a pointer to grad_student) is assigned to ps (a pointer to student), which is allowed because grad_student publicly inherits student.
  3. Polymorphism:
    • Virtual functions are essential for polymorphism. If student::print() is declared as virtual, then the derived class grad_student::print() will override it, and the appropriate function will be called depending on the actual type of the object that the pointer points to.

Corrected Code Example:
#include "student.h"  // Ensure this contains relevant class definitions

int main() {
    // Create base and derived class objects
    student s("Mae Pohl", 100, 3.425, fresh);
    grad_student gs("Morris Pohl", 200, 3.2564, grad, ta, "Pharmacy", "Retail Pharmacies");

    // Pointers to base and derived objects
    student* ps = &s;
    grad_student* pgs = nullptr;

    // Call base class print() using base class pointer
    ps->print(); // Calls student::print

    // Assign derived class pointer to base class pointer
    ps = pgs = &gs;

    // Call print() through base class pointer
    ps->print(); // If virtual, calls grad_student::print; otherwise, student::print

    // Call print() through derived class pointer
    pgs->print(); // Calls grad_student::print
}

Assumptions and Recommendations:
  1. Virtual Functions:
    • To achieve the correct polymorphic behavior, declare print() in the student class as virtual:

    • class student {
      public:
          virtual void print();
          // Other members
      };
              
  2. Pointer Symbols:
    • Replace & with & and -> with ->. These appear to be artifacts of incorrectly parsed HTML entities.
  3. Inheritance:
    • Ensure grad_student inherits publicly from student:
    • class grad_student : public student {
          // Derived class-specific members
      public:
          void print() override; // Overrides student::print
      };
              
  4. Use override:
    • In C++11 and later, use the override specifier in derived class methods to ensure you're correctly overriding a base class method.

Output (if `print()` is virtual):
  1. The first call (ps->print();) outputs the student class's print() function.
  2. The second call (ps->print();) outputs the grad_student class's print() function (polymorphic behavior).
  3. The third call (pgs->print();) directly outputs the grad_student class's print() function.
This function declares both objects and pointers to them. The conversion rule is that a pointer to a publicly derived class may be converted implicitly to a pointer to its base class. In our example, the pointer variable ps can point at objects of both classes, but the pointer variable pgs can point only at objects of type grad_student. We wish to study how different pointer assignments affect the invocation of a version of print().
ps -> print();

This invokes student::print(). It is pointing at the object s of type student.
ps = pgs = &gs;

This multiple assignment statement has both pointers pointing at an object of type grad_student. The assignment to ps involves an implicit conversion.
ps -> print();

This again invokes student::print(). The fact that this pointer is pointing at a grad_student object gs is not relevant.
pgs -> print();

This invokes grad_student::print(). The variable pgs is of type pointer to grad_student and, when invoked with an object of this type, selects a member function from this class.


Input Member Function - Exercise


SEMrush Software