Алмазная проблема с множественным наследованием С++

У меня есть домашнее задание с заданным кодом 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  

почему getname и getSex реализованы дважды с одним и тем же кодом? вы уверены, что это необходимо?

Federico 22.05.2019 16:55

Как InService узнать, какую функцию следует вызывать? Он имеет 2 различных реализации на выбор. virtual наследование помогает, если в классе основание реализован метод.

Yksisarvinen 22.05.2019 16:56

Почему sex и name собственность студентов и рабочих? У человека их нет?

Quimby 22.05.2019 17:02

@Federico, поэтому я следовал этому руководству, и, как я понял, он должен использовать одно и то же имя функции для работы с разными объектами. Например, базовый класс — shape, и он имеет виртуальную функцию getArea; у нас также есть производные классы, такие как Rectangle, Circle и Triangle. Поскольку для каждой формы у него разные вычисления, следовательно, нам нужно использовать виртуальную функцию. youtu.be/ng98qapa4Sw?t=1319

user10444434 22.05.2019 17:04

есть ли разница между Worker и Student ? У меня есть ощущение, что ваш дизайн нуждается в исправлении, но я действительно не понимаю, для чего вы хотите проектировать, скорее кажется, что вы могли бы забыть о наследовании, чтобы достичь аналогичного

463035818_is_not_a_number 22.05.2019 17:04

@Quimby Разве я не объявлял переменные пола и имени в классе Person? а студенты и рабочие получают его по наследству?

user10444434 22.05.2019 17:06

@Dr.raider да, но нет необходимости делать геттеры виртуальными, вы можете определить их в базе

463035818_is_not_a_number 22.05.2019 17:07

Дело в том, что это школьная задача, и код main.cpp работает на сервере, поэтому я не могу его изменить, мне нужно только реализовать код файла заголовка. Итак, взглянув на этот основной код функции, я подумал о наследовании. @ранееизвестный как_463035818

user10444434 22.05.2019 17:21

хорошо, тогда я понимаю. Было бы хорошо, если бы вы включили эту информацию в вопрос. Не разрешается изменять main, но необходимость заполнять дыры очень важна для понимания вашей проблемы.

463035818_is_not_a_number 22.05.2019 17:26

как только это устранено, также становится ясно, что вам не обязательно использовать алмаз. Теперь в основном зависит от вас, направлен ли ваш вопрос на исправление вашего бриллианта или решение реальной задачи;)

463035818_is_not_a_number 22.05.2019 17:28
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
1
10
439
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
 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.

Другие вопросы по теме