0 / 0 / 0
Регистрация: 29.06.2016
Сообщений: 4
1

Абстрактный класс, одиночное наследование, далее множественное

30.06.2016, 23:36. Показов 958. Ответов 10
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый вечер! никак не могу найти информацию о том, как правильно реализуется следующее действие: есть абстрактный класс А, от него получаем производный класс Б, от класса Б получаем 2 дочерних класса В1 и В2(публичное наследование), и далее от двух дочерних получаем Г(множественное наследование). То бишь получается ромбик с хвостиком(где хвост - АБК).
Вопрос:это вообще реализуется, если да, то как? При этом данные, расположенные в АБК, одни для всех(разумеется), а в классе Г нужно, чтобы данные-члены от дочерних классов пришли и с того, и с другого(также как и методы).Уже двое суток не могу с этим разобраться(
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.06.2016, 23:36
Ответы с готовыми решениями:

Абстрактный базовый класс и множественное наследование
Общая постановка. Создать программу с абстрактным базовым классом и множественным наследованием....

Абстрактный базовый класс и множественное наследование
Общая постановка. Создать программу с абстрактным базовым классом и множественным наследованием,...

Абстрактный базовый класс и множественное наследование (либо иерархия классов)
Помогите пожалуйста с задачей. Кое-что написал но еще далеко не все. Все ли пока правильно? ...

Абстрактный класс, наследование, класс хранится в другом классе
Нужна помощь. Написать программу: 1 класс. Имеется абстрактный класс который описывает какую-то...

10
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
01.07.2016, 00:05 2
Фейнман, Виртуальное наследование спасет отца русской демократии.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class A
{
public:
    void foo() { std::cout << "foo" << std::endl; }
};
 
class B : public virtual A {};
 
class C : public B {};
class D : public B {};
 
class E : public C, public D {};
 
int main()
{
    E e;
    e.foo();
}
0
383 / 281 / 31
Регистрация: 04.09.2009
Сообщений: 1,225
01.07.2016, 00:13 3
Виртуальное наследование решит твою проблему.

Рекомендуется к прочтению:http://en.cppreference.com/w/c... se_classes
0
0 / 0 / 0
Регистрация: 29.06.2016
Сообщений: 4
01.07.2016, 00:24  [ТС] 4
кажется я что-то не так делаю, приведу код(у каждого класса свой Unit,и думаю библиотеки подключены где надо))
абстрактный:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Base
{
    private:
           char *LastName;
           char *Name;
           char *MiddleName;
           int Age;
           bool Sex;
    public:
           Base();
           Base(int lengthL, int lengthN,int lengthM);
           virtual ~Base() {}                     //виртуальный деструктор
           virtual void ShowData(TMemo *) =0;                             //чисто виртуальная функция для вывода инфы
           void Set_LastName(char * LstNm);       //установка фамилии
           void Set_Name(char * Nm);             //установка имени
           void Set_MiddleName(char * MddlNm);   //установка отчества
           void Set_Age(int Ag);                 //установка возраста
           void Set_Sex(bool s);                 //установка пола
           char*  Get_LastName();                //чтение фамилии
           char* Get_Name();                      //чтение имени
           char* Get_MiddleName();                //чтение отчества
           int Get_Age();                        //чтение возраста
           bool Get_Sex();                       //чтение пола
    static int counter;
};
int Base::counter=-1;
производный от него:
C++
1
2
3
4
5
6
7
8
class Human : virtual public Base
{
    public:                                       //общедоступные методы
        Human();                                           //конструктор по умолчанию
        Human(int lengthL, int lengthN,int lengthM);       //конструктор для создания массива символов
        ~Human();                                          //деструктор
        virtual void ShowData(TMemo *);
};
на скрине представлен наследник от класса люди, курсор встает в указанное место ну и "ругается"
Миниатюры
Абстрактный класс, одиночное наследование, далее множественное  
0
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
01.07.2016, 02:07 5
Цитата Сообщение от Фейнман Посмотреть сообщение
на скрине представлен наследник от класса люди, курсор встает в указанное место ну и "ругается"
А заинклудить описание Human не забыли?
0
18988 / 9929 / 2427
Регистрация: 30.01.2014
Сообщений: 17,451
01.07.2016, 08:43 6
Цитата Сообщение от Фейнман Посмотреть сообщение
на скрине представлен наследник от класса люди, курсор встает в указанное место ну и "ругается"
Кроме указанного выше, нужно эти классы поместить между строками #define StudentClassUnitH и #endif. Проще говоря, #endif должен быть последней строкой в заголовочном файле.

Добавлено через 1 минуту
Фейнман, а еще лучше весь код сразу предоставить, т.к неизвестно сколько там еще разнообразных ошибок.
0
0 / 0 / 0
Регистрация: 29.06.2016
Сообщений: 4
01.07.2016, 10:42  [ТС] 7
Судя по всему ошибка именно в этих библиотеках(то бишь в порядке подключения). Привожу весь код:
абстрактный класс:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#ifndef BaseUnitH
#define BaseUnitH
//---------------------------------------------------------------------------
#endif
class Base
{
    private:
           char *LastName;
           char *Name;
           char *MiddleName;
           int Age;
           bool Sex;
    public:
           Base();
           Base(int lengthL, int lengthN,int lengthM);
           virtual ~Base() {}                     //виртуальный деструктор
           virtual void ShowData(TMemo *) =0;                             //чисто виртуальная функция для вывода инфы
           void Set_LastName(char * LstNm);       //установка фамилии
           void Set_Name(char * Nm);             //установка имени
           void Set_MiddleName(char * MddlNm);   //установка отчества
           void Set_Age(int Ag);                 //установка возраста
           void Set_Sex(bool s);                 //установка пола
           char*  Get_LastName();                //чтение фамилии
           char* Get_Name();                      //чтение имени
           char* Get_MiddleName();                //чтение отчества
           int Get_Age();                        //чтение возраста
           bool Get_Sex();                       //чтение пола
    static int counter;
};
int Base::counter=-1;
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#pragma hdrstop
#include<vcl.h>
#include "BaseUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
void Base::Set_LastName(char * LstNm)
{
        strcpy(LastName,LstNm);
}
void Base::Set_Name(char * Nm)
{
        strcpy(Name,Nm);
}
void Base::Set_MiddleName(char * MddlNm)
{
        strcpy(MiddleName,MddlNm);
}
void Base::Set_Age(int Ag)
{
    if(Ag<0 || Ag>150)
    ShowMessage("возраст введен некорректно");
    else
    Age=Ag;
}
void Base::Set_Sex(bool s)
{
    Sex=s;
}
char * Base::Get_LastName()
{
    return LastName;
}
char * Base::Get_Name()
{
    return Name;
}
char * Base::Get_MiddleName()
{
    return MiddleName;
}
int Base::Get_Age()
{
    return Age;
}
bool Base::Get_Sex()
{
    return Sex;
}
Base::Base()
{
    Sex=false;;
    Age=18;
    LastName="";
    Name="";
    MiddleName="";
}
Base::Base(int lengthL, int lengthN,int lengthM)
{
    Sex=0;
    Age=18;
    LastName=new char[lengthL];
    Name=new char[lengthN];
    MiddleName=new char[lengthM];
    counter++;
}
производный от него:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#ifndef HumanClassUnitH
#define HumanClassUnitH
//---------------------------------------------------------------------------
#endif
class Human : virtual public Base
{
    public:                                       //общедоступные методы
        Human();                                           //конструктор по умолчанию
        Human(int lengthL, int lengthN,int lengthM);       //конструктор для создания массива символов
        ~Human();                                          //деструктор
        virtual void ShowData(TMemo *);
};
 
#pragma hdrstop
#include<vcl.h>
#include"BaseUnit.h"
#include "HumanClassUnit.h"
//---------------------------------------------------------------------------
 
#pragma package(smart_init)
Human::Human():Base()
{
 
}
Human::Human(int lengthL, int lengthN,int lengthM):Base(lengthL,lengthN,lengthM)
{
 
}
Human::~Human()
{
 
}
void Human::ShowData(TMemo *txt)
{   char *sex; sex=new char[3];
    sex=(Get_Sex())?"жен":"муж";
    txt->Lines->Add(Get_LastName());
    txt->Lines->Strings[Base::counter]=txt->Lines->Strings[Base::counter]+"  "+Get_Name()+"  "+Get_MiddleName()+"  "+sex+"  "+IntToStr(Get_Age());;
    delete sex;
 
}
Первый дочерний:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#ifndef StudentClassUnitH
#define StudentClassUnitH
#include "HumanClassUnit.h"
//---------------------------------------------------------------------------
#endif
struct education         //структура для хранения данных массив символов-float
{   char *lesson;
    float mark;
};
class Student :  public Human                        //производный класс студент public наследование
{   private:
       int quantity;
       char *studies_job;
       float middle_mark;
       education *M;
    public:
       Student();
       Student(int Lengthm,int LengthL, int LengthN,int LengthM);
       ~Student();
       virtual void ShowData(TMemo *txt);
       bool Add_Mi(int dlina_str,char *txt,int nmb,int nmb_str); //чисто виртуальная ункция добавления строки в структуру
       void Set_Middle();
       float Get_Middle();
       void Set_Job(char *jb);
       char *Get_Job();
       void Set_Quantity(int quant);
       int Get_Quantity();
};
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#pragma hdrstop
#include<vcl.h>
#include "StudentClassUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
Student::Student():Human()                                       //
{
    quantity=0;
    middle_mark=0;
    studies_job="";
}
Student::Student(int Lengthm,int LengthL,int LengthN,int LengthM):Human(LengthL,LengthN,LengthM) //
{
    quantity=0;
    M = new education[quantity];
    middle_mark=0;
    studies_job=new char[Lengthm];
}
Student::~Student()                                     //
{
    delete [] M->lesson;
//  delete [] studies_job;
    delete [] M;
}
////
void Student::Set_Quantity(int quant)
{
    quantity=quant;
}
bool Student::Add_Mi(int dlina_str,char *txt,int nmb,int nmb_str)
{
    if(nmb_str<0 && nmb_str>=quantity)
     {
        return false;
     }
     M[nmb_str].lesson=new char[dlina_str];
     strcpy(M[nmb_str].lesson,txt);
     M[nmb_str].mark=nmb;
     return true;
}
void Student::ShowData(TMemo *txt)
{   char *sex; sex=new char[3];
    sex=(Sex)?"жен":"муж";
    txt->Lines->Add(LastName);
    txt->Lines->Strings[Base::counter]=txt->Lines->Strings[Base::counter]+"  "+Get_Name()+"  "+Get_MiddleName()+"  "+sex+"  "+IntToStr(Get_Age())+"  "+studies_job+"  "+FloatToStr(middle_mark);
    delete sex;
 
}
void Student::Set_Job(char *jb)
{
    strcpy(studies_job,jb);
}
void Student::Set_Middle()
{   float sum=0;
    for(int i=0;i<quantity;i++)
    sum+=M[i].mark;
    middle_mark=sum/quantity;
}
char *Student::Get_Job()
{
    return studies_job;
}
float Student::Get_Middle()
{
    return middle_mark;
}
int Student::Get_Quantity()
{
    return quantity;
}
Второй дочерний:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#ifndef WorkerClassUnitH
#define WorkerClassUnitH
//---------------------------------------------------------------------------
#endif
struct month_earn         //структура для хранения данных массив символов-float
{   char *month;
    float earning;
};
class Worker : public Human                       //производный класс рабочие public наследование
{
    private:
       char * office_job;                                  // место работы
       float middle_earnings;                             // средний заработок
       month_earn *M;                                    //структура о ежемесячной зарплате(месяц+зарплата)
       int quantity;                                   //количество месяцев работы
    public:
       Worker();
       Worker(int Lengthm,int LengthL, int LengthN,int LengthM);
       ~Worker();
       virtual void ShowData(TMemo *txt);
       bool Add_Mi(int dlina_str,char *txt,int nmb,int nmb_str); //чисто виртуальная ункция добавления строки в структуру
       void Set_Middle();
       float Get_Middle();
       void Set_Job(char *jb);
       char *Get_Job();
       void Set_Quantity(int quant);
       int Get_Quantity();
};
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#pragma hdrstop
#include<vcl.h>
#include"HumanClassUnit.h"
#include "WorkerClassUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
Worker::Worker():Human()
{
   office_job="";
   middle_earnings=0;
   quantity=0;
}
Worker::Worker(int Lengthm,int LengthL, int LengthN,int LengthM):Human(LengthL,LengthN,LengthM)
{   quantity=0;
    M=new month_earn[quantity];
    office_job=new char[Lengthm];
    middle_earnings=0;
}
Worker::~Worker()
{
    delete []M->month;
    delete []M;
//  delete []office_job;
}
///////
void Worker::ShowData(TMemo *txt)
{   char *sex; sex=new char[3];
    sex=(Human::Get_Sex())?"жен":"муж";
    txt->Lines->Add(Get_LastName());
    txt->Lines->Strings[Base::counter]=txt->Lines->Strings[Base::counter]+"  "+Get_Name()+"  "+Get_MiddleName()+"  "+sex+"  "+IntToStr(Get_Age())+"  "+office_job+"  "+FloatToStr(middle_earnings);
    delete sex;
}
void Worker::Set_Job(char *jb)
{
    strcpy(studies_job,jb);
}
void Worker::Set_Middle()
{   float sum=0;
    for(int i=0;i<quantity;i++)
    sum+=M[i].earning;
    middle_earnings=sum/quantity;
}
char *Worker::Get_Job()
{
    return office_job;
}
float Worker::Get_Middle()
{
    return middle_earnings;
}
int Worker::Get_Quantity()
{
    return quantity;
}
void Worker::Set_Quantity(int quant)
{
    quantity=quant;
}
bool Worker::Add_Mi(int dlina_str,char *txt,int nmb,int nmb_str)
{
    if(nmb_str<0 && nmb_str>=quantity)
     {
        return false;
     }
     M[nmb_str].month=new char[dlina_str];
     strcpy(M[nmb_str].month,txt);
     M[nmb_str].earning=nmb;
     return true;
}
Производный класс при множественном наследовании(ещё не заполнен):
C++
1
2
3
4
5
6
7
8
9
10
11
#ifndef StudWorkUnitH
#define StudWorkUnitH
//---------------------------------------------------------------------------
#endif
 class StudWork : public Student , public Worker
 {
     public:
         StudWork();
         ~StudWork();
         void ShowData(TMemo *txt);
 };
C++
1
2
3
4
5
6
7
8
9
10
11
#pragma hdrstop
#include<vcl.h>
#include"StudentClassUnit.h"
#include"WorkerClassUnit.h"
#include "StudWorkUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
void StudWork::ShowData(TMemo *txt)
{
    ShowMessage("продолжение следует");
}
Миниатюры
Абстрактный класс, одиночное наследование, далее множественное  
0
18988 / 9929 / 2427
Регистрация: 30.01.2014
Сообщений: 17,451
01.07.2016, 13:34 8
Фейнман, ну собственно мы выше уже сказали.

Заголовочные файлы с учетом этого должны выглядеть так:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef StudWorkUnitH
#define StudWorkUnitH
 
#include "StudentClassUnit.h"
#include "WorkerClassUnit.h"
 
//---------------------------------------------------------------------------
class StudWork : public Student, public Worker
{
public:
     StudWork();
     ~StudWork();
     void ShowData(TMemo *txt);
};
#endif
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#ifndef WorkerClassUnitH
#define WorkerClassUnitH
 
#include "HumanClassUnit.h"
//---------------------------------------------------------------------------
struct month_earn         //структура для хранения данных массив символов-float
{   char *month;
    float earning;
};
class Worker : public Human                       //производный класс рабочие public наследование
{
private:
   char * office_job;                                  // место работы
   float middle_earnings;                             // средний заработок
   month_earn *M;                                    //структура о ежемесячной зарплате(месяц+зарплата)
   int quantity;                                   //количество месяцев работы
public:
   Worker();
   Worker(int Lengthm,int LengthL, int LengthN,int LengthM);
   ~Worker();
   virtual void ShowData(TMemo *txt);
   bool Add_Mi(int dlina_str,char *txt,int nmb,int nmb_str); //чисто виртуальная ункция добавления строки в структуру
   void Set_Middle();
   float Get_Middle();
   void Set_Job(char *jb);
   char *Get_Job();
   void Set_Quantity(int quant);
   int Get_Quantity();
};
 
#endif
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#ifndef StudentClassUnitH
#define StudentClassUnitH
 
#include "HumanClassUnit.h"
//---------------------------------------------------------------------------
struct education         //структура для хранения данных массив символов-float
{   char *lesson;
    float mark;
};
class Student :  public Human                        //производный класс студент public наследование
{
private:
   int quantity;
   char *studies_job;
   float middle_mark;
   education *M;
public:
   Student();
   Student(int Lengthm,int LengthL, int LengthN,int LengthM);
   ~Student();
   virtual void ShowData(TMemo *txt);
   bool Add_Mi(int dlina_str,char *txt,int nmb,int nmb_str); //чисто виртуальная ункция добавления строки в структуру
   void Set_Middle();
   float Get_Middle();
   void Set_Job(char *jb);
   char *Get_Job();
   void Set_Quantity(int quant);
   int Get_Quantity();
};
 
#endif
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef HumanClassUnitH
#define HumanClassUnitH
 
#include "BaseUnit.h"
//---------------------------------------------------------------------------
class Human : virtual public Base
{
public:                                       //общедоступные методы
    Human();                                           //конструктор по умолчанию
    Human(int lengthL, int lengthN,int lengthM);       //конструктор для создания массива символов
    ~Human();                                          //деструктор
    virtual void ShowData(TMemo *);
};
 
#endif

В коде конечно еще дофига ошибок. Например определение статическоой переменной нужно перенести в cpp. Также есть несколько утечек памяти и потенциальная возможность записи за пределы выделенной памяти (см. закоменченое в деструкторах и конструктор по умолчанию, а также сеттеры, которые с этой памятью работают), нарушение const корректности (в ShowData), попытка освобождения статической памяти (в ShowData), ошибка из-за копи-паста (в Worker::Set_Job). Это навскидку.
1
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
01.07.2016, 14:02 9
Фейнман, Еще добавлю: Из вашего исходного поста следовало, что виртуально наследоваться надо от A. Когда вы предоставили код - виртуально наследоваться надо и/или от Human.
0
Ferrari F1
01.07.2016, 14:47
  #10

Не по теме:

Абстрактный класс, одиночное наследование, далее множественное

0
0 / 0 / 0
Регистрация: 29.06.2016
Сообщений: 4
01.07.2016, 19:53  [ТС] 11
Большое спасибо))) с библиотеками теперь стало все ясно)
0
01.07.2016, 19:53
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
01.07.2016, 19:53
Помогаю со студенческими работами здесь

Множественное наследование (Разработайте базовый класс CLIENT)
Задание: Множественное наследование. Разработайте базовый класс CLIENT. Элемент класса: ...

Абстрактный класс. Наследование
class polygon{ int height, width, point p; e_color color; public: ...

Наследование и абстрактный класс
Вот сделал список с такими условиями #include &lt;iostream&gt; #include &lt;conio.h&gt; #include &lt;string&gt;...

Множественное наследование: определить класс Окружность, вписанная в ромб
С помощью множественного наследования определить класс Окружность, вписанная в ромб. Классы Круг и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru