Кроме лишней скобки и пропущенной точки с запятой, в иерархии две копии RawHardDisk. Виртуальное наследование от общего предка устраняет неоднозначность disk.attach().
Найдите и исправьте ошибки в данном C++ коде
Кроме лишней скобки и пропущенной точки с запятой, в иерархии две копии RawHardDisk. Виртуальное наследование от общего предка устраняет неоднозначность disk.attach().
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
В этом задании необходимо выявить и устранить проблемы в следующем фрагменте программы на C++. Обратите внимание на корректность наследования и вызов методов базовых классов.
# include <iostream>
using namespace std;
class RawHardDisk {
public:
RawHardDisk() {
cout << "RawHardDisk constructor called" << endl;
}
void attach() {
cout << "Disk attached" << endl;
}
};
class CBTHardDisk: public RawHardDisk {
public:
CBTHardDisk() {
cout << "CBTHardDisk constructor called" << endl;
}
};
class SCSIHardDisk: public RawHardDisk {
public:
SCSIHardDisk() {
cout << "SCSIHardDisk constructor called" << endl;
}
};
class OVirtHardDisk: public SCSIHardDisk, public CBTHardDisk {}
}
int main() {
OVirtHardDisk disk;
disk.attach();
return 0;
}
Исправьте код так, чтобы он компилировался и корректно выводил сообщения о вызове конструкторов и методе attach.
Ответ
Кроме лишней скобки и пропущенной точки с запятой, в иерархии две копии RawHardDisk. Виртуальное наследование от общего предка устраняет неоднозначность disk.attach().
Существующие тела конструкторов можно сохранить, изменив объявления:
class CBTHardDisk : public virtual RawHardDisk {
public:
CBTHardDisk() { std::cout << "CBTHardDisk constructor called\n"; }
};
class SCSIHardDisk : public virtual RawHardDisk {
public:
SCSIHardDisk() { std::cout << "SCSIHardDisk constructor called\n"; }
};
class OVirtHardDisk : public SCSIHardDisk, public CBTHardDisk {};
RawHardDisk создаётся один раз, затем SCSIHardDisk, затем CBTHardDisk — по порядку базовых классов OVirtHardDisk. Вызов attach выводит Disk attached. Явное указание одной ветви без virtual тоже разрешило бы имя, но оставило бы два независимых базовых объекта.