Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.64/11: Рейтинг темы: голосов - 11, средняя оценка - 4.64
3 / 3 / 1
Регистрация: 02.03.2013
Сообщений: 231

Наследование

19.08.2020, 15:16. Показов 2655. Ответов 33

Студворк — интернет-сервис помощи студентам
Потихоньку изучаю С++. Разбираю реализацию ООП на этом языке.
Сделал простенькие класса для понимания концепции наследования.

Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Person
{
protected:
    std::string _name;
    unsigned int _age;
 
public:
    Person(std::string name, unsigned int age ) : _name{name}, _age{age} {}
    virtual ~Person() = default;
 
    virtual void print() { std::cout << _name << _age << std::endl; }
};
 
class Professor : public Person
{
public:
    Professor(std::string name, unsigned int age) : Person{ name, age } {}
    virtual ~Professor() = default;
 
    void print() override { std::cout << "Prof " << _name << " " << _age << std::endl; }
};


Решил добавить к этому контейнеры. Создал ещё два класса.

Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class House
{
public:
    virtual ~House() = default;
 
    virtual std::vector<Person*> get_person() { throw new std::exception("NotImplemented"); };
};
 
class University : public House
{
private:
    std::vector<Professor*> _professors;
public:
 
    std::vector<Person*> get_person() override{ return _professors; };
 
};

И тут началось. Не работает метод get_person() класса University. Не понимаю почему. dynamic_cast не помогает. Правда, я мб неправильно его использую? Делаю так
C++
1
dynamic_cast<std::vector<Person*>>(_professors)
. Что я делаю неправильно?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
19.08.2020, 15:16
Ответы с готовыми решениями:

Заменить наследование классов на наследование интерфейсов
#include &lt;iostream&gt; #include &lt;assert.h&gt; using namespace std; int people_on_base = 100; int vehicles_on_base = 100; double...

Наследование
Наследование 1)Должна быть табличка 3*3 2)Разные типы наследования 3)программа в в которой будет наследоваться клас 4) наследуются...

С++ Наследование
#include &lt;conio.h&gt; #include &lt;iostream.h&gt; class MyClass { int a; public: MyClass(int); show_a(int) ...

33
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
22.08.2020, 23:33
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от schoolboy_ Посмотреть сообщение
память в результирующем векторе будет выделяться при каждой вставке?
Вектор будет создаваться при каждом вызове этой функции. Но память под все элементы будет выделена сразу.

Цитата Сообщение от schoolboy_ Посмотреть сообщение
лучше создать результирующий вектор размером _professots.size() и туда скопировать по индексу?
Создание элемента в векторе уже подразумевает его инициализацию (и далее будет перезапись новым объектом старого). Чтоб этого не было, у вектора есть функция резервирования места под элементы (reserve), ей в подобных случаях и пользоваться (не будет лишнего создания элемента). Но не в этом.
1
264 / 153 / 33
Регистрация: 29.06.2019
Сообщений: 1,554
23.08.2020, 16:30
Цитата Сообщение от DrOffset Посмотреть сообщение
Вы в функции ждете std::vector<Person*> & и передаете std::vector<Person*>.
А в примере с возвратом вы заявили тип std::vector<Person*>, но возвращаете по факту std::vector<Professor*>
подправила на своё усмотрение (для примера работающего)
Кликните здесь для просмотра всего текста
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
71
72
73
74
75
76
// https://www.cyberforum.ru/cpp-beginners/thread2690819.html
// Наследование 
 
#include <iostream>
#include <vector>
#include <exception>
 
class Person
{
protected:
    std::string _name;
    unsigned int _age;
 
public:
    Person(std::string name, unsigned int age ) : _name{name}, _age{age} {}
    virtual ~Person() = default;
 
    virtual void print() { std::cout << _name << _age << std::endl; }
};
 
class Professor : public Person
{
public:
    Professor(std::string name, unsigned int age) : Person{ name, age } {}
    virtual ~Professor() = default;
 
    void print() override { std::cout << "Prof " << _name << " " << _age << std::endl; }
};
 
class House
{
public:
    virtual ~House() = default;
 
    virtual std::vector<Person*> get_person() {};       //   throw std::exception("NotImplemented");  
    
};
 
 
class University : public House
{
    private:
        std::vector<Person*> _professors;
    public:
     
    //void add_professor(Person* professor) { _professors.push_back(professor); }
        
    // вернуть контейнер
    std::vector<Person*> get_person() override { 
            return std::vector<Person *>(_professors.begin(), _professors.end());
        }
     
    void f(std::vector<Person*>& persons)
        {
            for (auto person : persons)
                person->print();
        }
};
 
 
int main(int argc, const char *argv[])
{    
    Person* p = new Person("Oleg", 18);
    Person* prof = new Professor("Bjarne Stroustrup", 54);
     
    std::vector<Person*> persons(2);
    persons[0] = p;
    persons[1] = prof;
     
    // передача ссылки
    std::vector<Person*>& refP=persons;     
    University u;
    u.f(refP);
 
    return 0;
}

отдельно add_professor не вижу смысла в классе university
хотя с person'ами и прфессорами всё равно как-то туманно...
всё-таки add_person и add_professor ещё доработать бы
1
3 / 3 / 1
Регистрация: 02.03.2013
Сообщений: 231
23.08.2020, 21:25  [ТС]
Цитата Сообщение от TRam_ Посмотреть сообщение
Создание элемента в векторе уже подразумевает его инициализацию (и далее будет перезапись новым объектом старого).
т.е. если я пишу так:

C++
1
std::vector<Person> persons(10);
то будет не просто зарезервирована память под десять элементов типа Person. Для каждого элемента будет вызван конструктор по-умолчанию?
0
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
23.08.2020, 22:48
schoolboy_, да.

Добавлено через 5 минут
А вот так:
C++
1
2
std::vector<Person> persons;
persons.reserve(10);
будет зарезервирована память, но никаких конструкторов элементов не вызовется. Они (конструкторы копирования) вызовутся при push_back, а при emplace_back - конструкторы перемещения.
1
3 / 3 / 1
Регистрация: 02.03.2013
Сообщений: 231
24.08.2020, 06:23  [ТС]
Что-то не сходится. Для Person и Professor нет конструктора по умолчанию. Так что будет вызывать компилятор?
0
264 / 153 / 33
Регистрация: 29.06.2019
Сообщений: 1,554
24.08.2020, 07:53
Цитата Сообщение от schoolboy_ Посмотреть сообщение
Для Person и Professor нет конструктора по умолчанию. Так что будет вызывать компилятор?
ликбез
При создании объекта класса, который не содержит ни одного конструктора, будет вызываться неявно заданный конструктор по умолчанию (default constructor), выделяющий память для объекта класса. Однако, в классе можно объявить собственный конструктор по умолчанию. Такой конструктор называется: явно заданный конструктор по умолчанию.
Кликните здесь для просмотра всего текста
If I define the following class
class X
{};

The compiler will define the following methods:
X::X() {} // Default constructor. It takes zero arguments (hence default).
X::~X() {} // Destructor
X::X(X const& rhs) {}; // Copy constructor
X& operator=(X const& rhs)
{return *this;} // Assignment operator.

Note:
The default constructor is not built if ANY constructor is defined.
The other methods are not built if the user defines an alternative
и общим планом - Порядок вызова конструктора / деструктора в C ++
0
3 / 3 / 1
Регистрация: 02.03.2013
Сообщений: 231
24.08.2020, 08:26  [ТС]
JeyCi, компилятор создаст конструктор по умолчанию, только если не задан не один конструктор? Но если пользователь задал конструктор сам, то компилятор ничего делать не будет. В классе Person и Professor есть пользовательские конструкторы.
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
24.08.2020, 09:04
Цитата Сообщение от schoolboy_ Посмотреть сообщение
Что-то не сходится. Для Person и Professor нет конструктора по умолчанию. Так что будет вызывать компилятор?
Правильно говорить, что для элементов вектора осуществляется инициализация.
Инициализация в С++ может происходить не только посредством конструкторов.
1
3 / 3 / 1
Регистрация: 02.03.2013
Сообщений: 231
24.08.2020, 09:06  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Инициализация в С++ может происходить не только посредством конструкторов.
а как ещё?
и что в итоге будет генерировать компилятор глядя на такой код:
C++
1
std::vector<Person> persons(10)
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
24.08.2020, 09:10
Вот это
Цитата Сообщение от schoolboy_ Посмотреть сообщение
В классе Person и Professor есть пользовательские конструкторы.
и это
Цитата Сообщение от schoolboy_ Посмотреть сообщение
т.е. если я пишу так:
C++
1
std::vector<Person> persons(10);
то будет не просто зарезервирована память под десять элементов типа Person. Для каждого элемента будет вызван конструктор по-умолчанию?
просто даст ошибку компиляции, т.к. конструкторов по умолчанию у ваших классов нет.

Добавлено через 2 минуты
Цитата Сообщение от schoolboy_ Посмотреть сообщение
а как ещё?
Тут: https://en.cppreference.com/w/... ialization

В целом это сейчас не относится к теме. Я просто уточнил, что говорить в общем случае о конструкторах применительно к вектору не совсем корректно. Вектор выполняет инициализацию. Иногда она приводит к вызовам соответствующих конструкторов. Но, например, вектор из int никаких конструкторов не вызывает, по причине того, что у элементарных типов нет конструкторов. Вместо этого выполняется, например, zero-initialization.
1
264 / 153 / 33
Регистрация: 29.06.2019
Сообщений: 1,554
24.08.2020, 13:59
как-то почище
Кликните здесь для просмотра всего текста
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
71
72
73
74
75
76
77
78
79
80
// https://www.cyberforum.ru/cpp-beginners/thread2690819.html
// Наследование 
 
#include <iostream>
#include <vector>
#include <exception>
 
class Person
{
protected:
    std::string _name;
    unsigned int _age;
 
public:
    Person(std::string name, unsigned int age ) : _name{name}, _age{age} {}
    virtual ~Person() = default;
 
    virtual void print() { std::cout << _name << " " <<  _age << std::endl; }
};
 
class Professor : public Person
{
public:
    Professor(std::string name, unsigned int age) : Person{ name, age } {}
    virtual ~Professor() = default;
 
    void print() override { std::cout << "Prof " << _name << " " << _age << std::endl; }
};
 
class House
{
public:
    virtual ~House() = default;
 
    virtual std::vector<Person*> get_person() {};       //   throw std::exception("NotImplemented");  
    
};
 
 
class University : public House
{
    private:
        std::vector<Person*> _stuff;
    //    int _sz;
    public:
     
    // int& getSize(){return _sz;}
     
    void add_person(Person* aPerson) { _stuff.push_back(aPerson); }
    
    void add_professor(Person* aProfessor) { _stuff.push_back(aProfessor); }
        
    // вернуть контейнер
    std::vector<Person*> get_person() override { 
            return std::vector<Person *>(_stuff.begin(), _stuff.end());
        }
        
    // print 
    void printAll() // std::vector<Person*>& persons
        {
            for (auto person : _stuff)
                person->print();
        }
};
 
 
int main(int argc, const char *argv[])
{       
    University u;
    
    Person* p = new Person("Oleg", 18);
    Person* prof = new Professor("Bjarne Stroustrup", 54);  
    Person* p2 = new Person("Nick", 18);
    u.add_person(p);
    u.add_person(p2);
    u.add_professor(prof);
    // вывод НАСЛЕДУЕТСЯ... 
    u.printAll();
    return 0;
}

но с деструктором ещё разобраться, наверно... т.к. всё-таки память выделяется... значит и delete надо задействовать... чтобы не было утечки памяти... и висячих указателей в данном случае
0
24.08.2020, 14:03

Не по теме:

Цитата Сообщение от JeyCi Посмотреть сообщение
"Bjarne Stroustrup", 54
Вы этот код 16 лет назад писали? :)

0
24.08.2020, 14:06

Не по теме:

я его у ТС'а взяла... теперь будем знать, когда у Stroustrup'а день рождения )) - см #32

0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
24.08.2020, 14:17
Цитата Сообщение от JeyCi Посмотреть сообщение
C++
1
2
3
4
    // вернуть контейнер
    std::vector<Person*> get_person() override { 
            return std::vector<Person *>(_stuff.begin(), _stuff.end());
        }
В этом необходимость отпадает, т.к. у вас в классе std::vector<Person *> хранится, а не std::vector<Professor *>.
Т.е. можно просто:
C++
1
2
3
    std::vector<Person*> get_person() override { 
            return _stuff;
        }
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
24.08.2020, 14:17

наследование
Пытаюсь разобраться в наследовании Есть класс class File { public: struct comp { char num; // Имя переменной char st;...

Наследование
На основе класса «Массив» создать производный класс «Ассоциативный массив». Данный класс содержит массив указателей, каждый из которых...

наследование
Задача : Базовый класс: class Shape2D { public: Shape2D(); virtual ~ Shape2D(); virtual float Area( )= 0; virtual...

Наследование
Реализовать наследование классов квартиры,этаж,подъезд,дом

Наследование
Суть задачи: Реализуйте класс символьная строка,наследуйте от него класс двоичная строка. Реализуйте методы Show(от базовой строки) ...


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

Или воспользуйтесь поиском по форуму:
34
Ответ Создать тему
Новые блоги и статьи
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть не большие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru