Search code examples
c++inheritancepolymorphismmultiple-inheritancescoping

Is scoping a legitimate way to access virtual functions?


I have a C++ program with 4 classes : Person, Student, Employee, and PartTimeStudent.

Student and Employee each derive from Person, and PartTimeStudent derives from all 3 classes (making it the most derived class). All classes have a virtual function called VDescribe().

Please see the code below :

class Person
{
    ...    
    virtual void VDescribe();
    ...
};

class Student : virtual public Person
{
    ...    
    virtual void VDescribe();
    ...
};

class Employee : virtual public Person
{
    ...    
    virtual void VDescribe();
    ...
};

class PartTimeStudent : virtual public Person,
    virtual public Student,
    virtual public Employee
{
    ...    
    virtual void VDescribe();
    ...
};

Note : In the code snippet above I have omitted the Constructors, Destructors and member variables because they are not relevant to the question.

In addition, I have the following code in which a PartTimeStudent object is created and accessed via a pointer. I use scoping to invoke the VDescribe() functions of the different sub-objects within the PartTimeStudent object.

void DoTest()
{
    PartTimeStudent* pPTS = new PartTimeStudent("John", 23, "NTU", "Seven-Eleven");

    pPTS->VDescribe();
    pPTS->::Person::VDescribe();
    pPTS->::Student::VDescribe();
    pPTS->::Employee::VDescribe();
}

The code compiles successfully and I am able to invoke the different versions of VDescribe(). What I want to know is, is this a legitimate means of accessing virtual functions? Is this acceptable or a discouraged practice?


Solution

  • Yes, this is a perfectly legal way of bypassing dynamic dispatch and calling a particular version of a virtual function, not its final overrider.

    However, I would generally find it strange to see such code on the outside of the class, and I'd be checking to see if there's perhaps a design problem or misunderstanding. Normally, such code is used inside the class itself to call the overridden version of a function (typically from the overrider).