У меня есть домашнее задание с заданным кодом main.cpp, который нельзя изменить. В соответствии с этим main.cpp и простым примером Вход и выход (который приведен ниже) я должен закончить программу. Мои попытки: я пытаюсь создать 4 класса, класс Person; класс Рабочий; класс Студент; класс InService; в моей основной функции путем создания экземпляра объекта класса InService я передаю 4 параметра (имя, пол, номер ученика, номер работника); и с помощью указателя типа базового класса получить желаемый результат. Ошибка, которую он показывает: [Ошибка] нет уникального окончательного переопределения для «виртуального std::string Person::getName()» в «InService» [Ошибка] нет уникального окончательного переопределения для 'virtual int Person::getSex()' в 'InService'
Я пытался использовать для этого виртуальное наследование, но не могу понять, как решить эту проблему. Я провел некоторое исследование виртуального наследования и сослался на других экспертов ответы, но все еще путаюсь во всем ООП.
//Inservice.h
#include<string>
using namespace std;
class Person{
public:
Person();
~Person();
string name;
int sex;
virtual string getName() = 0;
virtual int getSex() = 0;
};
///////////////////////////////////////////////////
class Student:virtual public Person{
public:
Student();
~Student();
string sno;
virtual string getName() {
return name;
}
virtual int getSex(){
return sex;
}
string getSno(){
return sno;
}
};
//////////////////////////////////////////////////
class Worker:virtual public Person{
public:
Worker();
~Worker();
string wno;
virtual std::string getName(){
return name;
}
virtual int getSex(){
return sex;
}
string getWno(){
return wno;
}
};
///////////////////////////////////////////////////////
class InService: public Student, public Worker{
public:
InService(string _name, int _sex, string _sno, string _wno){
Person::name = _name;
Person::sex - _sex;
Worker::wno = _wno;
Student::sno = _sno;
}
};
///////////////////////////////////////////////////////
//main.cpp
#include <iostream>
#include "inservice.h"
using namespace std;
int main() {
string name, sno, wno;
int sex;
cin >> name;
cin >> sex;
cin >> sno;
cin >> wno;
InService is(name, sex, sno, wno);
Person* p = &is;
Student* s = &is;
Worker* w = &is;
cout << p->getName() << endl;
cout << p->getSex() << endl;
cout << s->getName() << endl;
cout << s->getSex() << endl;
cout << s->getSno() << endl;
cout << w->getName() << endl;
cout << w->getSex() << endl;
cout << w->getWno() << endl;
return 0;
}
Предположим, мой ввод:
Jack
1 //1-for male; 0 -for female
12345678 //studentNo
87654321 //workerNo
Я ожидаю, что вывод будет:
Jack
1
12345678
Jack
1
87654321
Как InService узнать, какую функцию следует вызывать? Он имеет 2 различных реализации на выбор. virtual наследование помогает, если в классе основание реализован метод.
Почему sex и name собственность студентов и рабочих? У человека их нет?
@Federico, поэтому я следовал этому руководству, и, как я понял, он должен использовать одно и то же имя функции для работы с разными объектами. Например, базовый класс — shape, и он имеет виртуальную функцию getArea; у нас также есть производные классы, такие как Rectangle, Circle и Triangle. Поскольку для каждой формы у него разные вычисления, следовательно, нам нужно использовать виртуальную функцию. youtu.be/ng98qapa4Sw?t=1319
есть ли разница между Worker и Student ? У меня есть ощущение, что ваш дизайн нуждается в исправлении, но я действительно не понимаю, для чего вы хотите проектировать, скорее кажется, что вы могли бы забыть о наследовании, чтобы достичь аналогичного
@Quimby Разве я не объявлял переменные пола и имени в классе Person? а студенты и рабочие получают его по наследству?
@Dr.raider да, но нет необходимости делать геттеры виртуальными, вы можете определить их в базе
Дело в том, что это школьная задача, и код main.cpp работает на сервере, поэтому я не могу его изменить, мне нужно только реализовать код файла заголовка. Итак, взглянув на этот основной код функции, я подумал о наследовании. @ранееизвестный как_463035818
хорошо, тогда я понимаю. Было бы хорошо, если бы вы включили эту информацию в вопрос. Не разрешается изменять main, но необходимость заполнять дыры очень важна для понимания вашей проблемы.
как только это устранено, также становится ясно, что вам не обязательно использовать алмаз. Теперь в основном зависит от вас, направлен ли ваш вопрос на исправление вашего бриллианта или решение реальной задачи;)





InService(string _name, int _sex, string _sno, string _wno){
Person::name = _name;
Person::sex - _sex;
Worker::wno = _wno;
Student::sno = _sno;
}
Там опечатка, Person::sex - _sex; должно быть Person::sex = _sex;
Также вы можете удалить виртуальные функции имени и пола и сделать их просто стандартными функциями в Person, поскольку они абсолютно одинаковы для всех производных от них классов. Это устранит двусмысленность в отношении того, на какую функцию getName и getSex должна указывать виртуальная таблица класса InService.
почему getname и getSex реализованы дважды с одним и тем же кодом? вы уверены, что это необходимо?