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

У меня есть домашнее задание с заданным кодом 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
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
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.

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