У меня есть программа на C ++ с 4 классами: Person, Student, Employee и PartTimeStudent.
Студент и Сотрудник являются производными от Person, а PartTimeStudent — от всех 3 классов (что делает его самым производным классом). Все классы имеют виртуальную функцию VDescribe ().
Пожалуйста, смотрите код ниже:
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();
...
};
Примечание. В приведенном выше фрагменте кода я опустил конструкторы, деструкторы и переменные-члены, поскольку они не имеют отношения к вопросу.
Кроме того, у меня есть следующий код, в котором объект PartTimeStudent создается и доступен через указатель. Я использую область видимости для вызова функций VDescribe () различных подобъектов в объекте PartTimeStudent.
void DoTest()
{
PartTimeStudent* pPTS = new PartTimeStudent("John", 23, "NTU", "Seven-Eleven");
pPTS->VDescribe();
pPTS->::Person::VDescribe();
pPTS->::Student::VDescribe();
pPTS->::Employee::VDescribe();
}
Код успешно компилируется, и я могу вызывать различные версии VDescribe (). Я хочу знать, является ли это законным средством доступа к виртуальным функциям? Это приемлемо или не рекомендуется?
Да, это совершенно законный способ обхода динамической диспетчеризации и вызова определенной версии виртуальной функции, а не ее окончательного переопределения.
Однако, как правило, было бы странно видеть такой код на вне класса, и я бы проверил, возможно, есть проблема дизайна или недоразумение. Обычно такой код используется внутри сам класс для вызова переопределенной версии функции (обычно из переопределителя).
Это законный способ не-виртуально вызвать эти функции. Там нет общего запрета, но вы должны быть осторожны при выполнении этого в конструкторах (так как ваши базовые классы virtual
). Вы должны точно знать, что именованный базовый подобъект уже существует. Для не виртуальных базовых классов это не проблема, так как они построены по порядку.