С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/18: Рейтинг темы: голосов - 18, средняя оценка - 4.89
17 / 17 / 2
Регистрация: 29.10.2013
Сообщений: 269
1

Узнать имя базового класса

09.05.2020, 12:47. Показов 3387. Ответов 10

Author24 — интернет-сервис помощи студентам
Есть базовый класс А. От него наследуются классы В и С.
Как узнать, что В и С наследуются именно от А? Я знаю про std::type_info.name(), но он показывает имя текущего класса.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
09.05.2020, 12:47
Ответы с готовыми решениями:

Как узнать тип производного класса в функции базового
Всем привет! Есть иерархия классов: class1 -> class2->class3 class2->class4 ...

Как узнать имя экземпляра класса?
у меня есть класс polynom, я создаю его экземпляры polynom a(5), b(5), c(5); как мне программно...

Вызов метода производного класса через обращение к методу базового класса
Добрый день. Изучаю основы ООП, наткнулся на проблему. Если создавать классы внутри main.cpp,...

Создать объект производного класса с передачей параметров в конструктор базового класса
Доброго времени суток! Если не затруднит, утолите мой интерес, пожалуйста! Есть базовый и...

10
Вездепух
Эксперт CЭксперт С++
12798 / 6674 / 1796
Регистрация: 18.10.2014
Сообщений: 16,894
09.05.2020, 12:54 2
Цитата Сообщение от nublin1 Посмотреть сообщение
Есть базовый класс А. От него наследуются классы В и С.
Как узнать, что В и С наследуются именно от А? Я знаю про std::type_info.name(), но он показывает имя текущего класса.
Что значит "узнать"? Зачем? В каком контексте? Что именно вы пытаетесь сделать?

Список базовых классов - информация времени компиляции. Ее не нужно "узнавать" - она и так заранее известна.
0
Комп_Оратор)
Эксперт по математике/физике
9005 / 4704 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
09.05.2020, 12:58 3
Лучший ответ Сообщение было отмечено nublin1 как решение

Решение

Цитата Сообщение от nublin1 Посмотреть сообщение
Есть базовый класс А. От него наследуются классы В и С.
Как узнать, что В и С наследуются именно от А? Я знаю про std::type_info.name(), но он показывает имя текущего класса.
Ечсли кастится автоматически и не is_same то это оно. У Александреску Современное проектирование на С++ показано хорошо. Посмотрите. Хотя есть и стандартные:
https://ru.cppreference.com/w/cpp/types/is_base_of
но для наглядности советую Александреску посмотреть, также . Это признанная нестареющая классика.
1
17 / 17 / 2
Регистрация: 29.10.2013
Сообщений: 269
09.05.2020, 12:59  [ТС] 4
хотел написать шаблонную функцию, которая добавляет передаваемый класс в 1 из массивов, в зависимости от его типа. Просто что бы, не проверять все, скажем, фигуры, а только их базовый класс
0
Комп_Оратор)
Эксперт по математике/физике
9005 / 4704 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
09.05.2020, 13:48 5
Цитата Сообщение от nublin1 Посмотреть сообщение
хотел написать шаблонную функцию, которая добавляет передаваемый класс в 1 из массивов, в зависимости от его типа. Просто что бы, не проверять все, скажем, фигуры, а только их базовый класс
Вы в псевдо коде покажите хотя бы, а то по русски оно не слагается.
1 Что принимает функция?//она разнотипные указатели не может же? Или void * - но это С и наследование в болото?
2 Что делает с тем что приняла?
3 Если что-то возвращает - что?
0
17 / 17 / 2
Регистрация: 29.10.2013
Сообщений: 269
09.05.2020, 14:27  [ТС] 6
Цитата Сообщение от IGPIGP Посмотреть сообщение
Вы в псевдо коде покажите хотя бы, а то по русски оно не слагается.
1 Что принимает функция?//она разнотипные указатели не может же? Или void * - но это С и наследование в болото?
2 Что делает с тем что приняла?
3 Если что-то возвращает - что?
__________________
Хотелось бы что то вроде этого:

C++
1
2
3
4
5
template <class Т>
void Components::addComponent(T t) {
// Если t является одной из фигур (шар,куб, и т.д. ), то добавить в массив vector<Figure> figures
// Если t является машиной, то добавить в массив vector<Car> cars
}
Просто все фигуры наследуются от одного базового класса - Figure. И легче было бы сравнить на принадлежность к нему, чем проходить проверку на все классы фигур
0
Комп_Оратор)
Эксперт по математике/физике
9005 / 4704 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
09.05.2020, 17:07 7
Цитата Сообщение от nublin1 Посмотреть сообщение
Просто все фигуры наследуются от одного базового класса - Figure. И легче было бы сравнить на принадлежность к нему, чем проходить проверку на все классы фигур
А - понял кажись, - есть два базовых в промежуточной ступени?
Чтобы разобрать их наслеников нужно проверять по RTTI погуглите, почитайте и возвращайтесь.

Добавлено через 53 минуты
Цитата Сообщение от nublin1 Посмотреть сообщение
// Если t является одной из фигур (шар,куб, и т.д. ), то добавить в массив vector<Figure> figures
// Если t является машиной, то добавить в массив vector<Car> cars
}
Это вам рано. Если вы и впрямь позаталкиваете детей в родительские гробики - отрежете им ноги. Тут указатели нужны. Причём что-то из смартов - unique_ptr может быть. Но тогда разобрать по категориям будет маловато. Тут фабрички надо писать и билдер над ними какой-то. Разбироать придётся конкретно так как конструкторы виртуальными не бывают. Вот простой код считающий овец прыгающих через плетень:
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
81
82
83
84
85
#include <iostream>
#include <vector>
 
using namespace std;
 
struct Everything
{
virtual ~Everything(){}
};
 
struct Figure :public Everything
{
 
};
struct Car :public Everything
{
 
};
 
struct EvilTroll :public Everything
{
 
};
 
struct Triangle :public Figure
{
 
};
struct Cube :public Figure
{
 
};
 
struct Ford :public Car
{
 
};
 
struct Vaz :public Car //cry
{
 
};
 
int selector( const Everything &WTFigure )
              {
 
                  if(dynamic_cast<const Car*>(&WTFigure))
                  {
                      return 1;
                  }
 
                  else
                  if(dynamic_cast<const Figure*>(&WTFigure))
                  {
                      return 0;
                  }
                  return -1;
              }
 
int main()
{
vector<Everything*> everything
{
    new Triangle,
    new Cube,
    new Ford,
    new Cube,
    new Vaz,
    new EvilTroll
};
 
int car(0), figure(0), unknown(0);
for(const auto &el:everything)
{
    if(1 == selector(*el))car++;
    if(0 == selector(*el))figure++;
    if(-1 == selector(*el))unknown++;
}
 
cout<<"car= "<< car  << ' '
    <<"figure= "<< figure  << ' '
    <<"unknown= "<< unknown  << ' ' << endl;
 
return 0;
}
0
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
09.05.2020, 17:19 8
Цитата Сообщение от nublin1 Посмотреть сообщение
// Если t является одной из фигур (шар,куб, и т.д. ), то добавить в массив vector<Figure> figures
// Если t является машиной, то добавить в массив vector<Car> cars
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
// Если t является одной из фигур (шар,куб, и т.д. ), то добавить в массив vector<Figure> figures
// Если t является машиной, то добавить в массив vector<Car> cars
 
// Через if constexpr (C++17)
template <class Т>
void addComponent(T * t) {
    if constexpr(std::is_base_of<Figure, T>::value) {
        figures.push_back(t); // vector<Figure *> figures
    }
    else if constexpr(std::is_base_of<Car, T>::value) {
        cars.push_back(t); // vector<Car *> cars
    }
    // возможно лучше заменить на vector<unique_ptr<Car>> и vector<unique_ptr<Figure>> figures, но это уже вам решать исходя из целей кода
}
 
////////////////////////////
 
 
// Классический подход - перегрузка
void addComponentImpl(Car * t) { // private method
    cars.push_back(t); // vector<Car *> cars
}
void addComponentImpl(Figure * t) { // private method
    figures.push_back(t); // vector<Figure *> figures
}
 
template <class Т>
void addComponent(T * t) {
    addComponentImpl(t);
}
1
Комп_Оратор)
Эксперт по математике/физике
9005 / 4704 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
09.05.2020, 18:28 9
Ну то есть да, если указатели на вызывающей стороне уже инициализированы, то можно и с владением разобраться.
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <iostream>
#include <vector>
#include <memory>
#include <initializer_list>
 
using namespace std;
 
struct Everything
{
virtual ~Everything(){}
};
 
struct Figure :public Everything
{
 
};
struct Car :public Everything
{
 
};
 
struct EvilTroll :public Everything
{
 
};
 
struct Triangle :public Figure
{
 
};
struct Cube :public Figure
{
 
};
 
struct Ford :public Car
{
 
};
 
struct Vaz :public Car //cry
{
 
};
 
int selector(const unique_ptr<Everything> &WTFigure )
              {
 
                  if(dynamic_cast< Car*>(WTFigure.get()))
                  {
                      return 1;
                  }
 
                  else
                  if(dynamic_cast< Figure*>(WTFigure.get()))
                  {
                      return 0;
                  }
                  return -1;
              }
 
void distributor(
                unique_ptr<Everything> &WTFigure,
                vector<unique_ptr<Car>> &cars,
                vector<unique_ptr<Figure>> &figures
                 )
              {
 
                  if(Car* pcar=dynamic_cast< Car*>(WTFigure.get()))
                  {
                      cars.push_back(unique_ptr<Car>(pcar));
                      WTFigure.release();
                  }
                  else
                  if(Figure* pfig=dynamic_cast< Figure*>(WTFigure.get()))
                  {
                      figures.push_back(unique_ptr<Figure>(pfig));
                      WTFigure.release();
                  }
 
              }
 
template<typename T>
std::vector<T> vector_from(std::initializer_list<T> il)
{
  std::vector<T> result;
  result.reserve(il.size());
  for (auto& e : il)
    result.push_back(std::move(const_cast<T&>(e)));
  return result;
}
 
int main()
{
std::initializer_list<unique_ptr<Everything>> ilist=
{
    unique_ptr<Everything>(new Triangle),
    unique_ptr<Everything>(new Cube),
    unique_ptr<Everything>(new Ford),
    unique_ptr<Everything>(new Cube),
    unique_ptr<Everything>(new Vaz),
    unique_ptr<Everything>(new EvilTroll)
};
vector<unique_ptr<Everything>> everything=vector_from(ilist);
 
int car(0), figure(0), unknown(0);
for(const auto &el:everything)
{
    if(1 == selector(el))car++;
    if(0 == selector(el))figure++;
    if(-1 == selector(el))unknown++;
}
 
cout<<"car= "<< car  << ' '
    <<"figure= "<< figure  << ' '
    <<"unknown= "<< unknown  << ' ' << endl;
 
vector<unique_ptr<Car>> cars;
                vector<unique_ptr<Figure>> figures;
 
for(auto &el:everything)
{
    distributor(el, cars,figures) ;
}
 
cout<<"car= "<< cars.size()  << ' '
    <<"figure= "<< figures.size() <<  endl;
return 0;
}
0
17 / 17 / 2
Регистрация: 29.10.2013
Сообщений: 269
09.05.2020, 19:31  [ТС] 10
Эм.. А вот вроде короткая запись. И работает (если объект unique_ptr )

C++
1
2
3
4
5
6
template <class C>
void Components::addComponent(C component) {    
    if (std::is_base_of< Figure , C>::value == true) {
        figures.push_back(component);
    }
}
0
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
09.05.2020, 20:02 11
Цитата Сообщение от nublin1 Посмотреть сообщение
И работает
В частном случае только работает. Если вы добавите еще одну условие (как вы первоначально хотели), то работать перестанет в случаях, когда С не совместим с одним из типов контейнера.

И в этом коде еще одна проблема: срезка. В результате может получиться совсем не то, что вы хотели бы (хоть внешне и выглядит рабочим).
0
09.05.2020, 20:02
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
09.05.2020, 20:02
Помогаю со студенческими работами здесь

Почему объект производного класса не видит префиксный оператор из базового класса?
Короче создал я базовый класс с перегруженным префиксным оператором ++. Потом чтоб его...

Как сложить объект базового класса с объектом производного(наследуемого класса)
Как умножить объект базового класса с объектом производного(наследуемого класса): ozenka - объект...

Перегрузка оператора >> для дочернего класса от базового виртуального класса
Доброго вам времени суток! Программирую на С++ не давно, в связи с отсутствием должного времени на...

Создание указателя типа базового класса на экземпляр производного класса
Добрый день! Иногда видел коды, где создавался указатель типа базового класса на объект класса -...

Указатель на объект базового класса и адрес объекта производного класса
Пример кода: class Class1 { public: Class1(int x) { j = new int; *j = x; }...

Вызвать конструктор производного класса без конструктора базового класса
Здравствуйте! У меня есть базовый класс треугольник и производный класс равносторонний...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Блоги программистов
Как перейти с Options API на Composition API в Vue.js
BasicMan 06.01.2025
Почему переход на Composition API актуален В мире современной веб-разработки фреймворк Vue. js продолжает эволюционировать, предлагая разработчикам все более совершенные инструменты для создания. . .
Архитектура современных процессоров
inter-admin 06.01.2025
Процессор (центральный процессор, ЦП) является основным вычислительным устройством компьютера, которое выполняет обработку данных и управляет работой всех остальных компонентов системы. Архитектура. . .
История создания реляционной модели баз данных, правила Кодда
Programming 06.01.2025
Предпосылки создания реляционной модели В конце 1960-х годов компьютерная индустрия столкнулась с серьезными проблемами в области управления данными. Существовавшие на тот момент модели данных -. . .
Полезные поделки на Arduino, которые можно сделать самому
raxper 06.01.2025
Arduino как платформа для творчества Arduino представляет собой удивительную платформу для технического творчества, которая открывает безграничные возможности для создания уникальных проектов. Эта. . .
Подборка решений задач на Python
IT_Exp 06.01.2025
Целью данной подборки является предоставление возможности ознакомиться с различными задачами и их решениями на Python, что может быть полезно как для начинающих, так и для опытных программистов. . . .
С чего начать программировать микроконтроллер­­ы
raxper 06.01.2025
Введение в мир микроконтроллеров Микроконтроллеры стали неотъемлемой частью современного мира, окружая нас повсюду: от простых бытовых приборов до сложных промышленных систем. Эти маленькие. . .
Из чего собрать игровой компьютер
inter-admin 06.01.2025
Сборка игрового компьютера требует особого внимания к выбору комплектующих и их совместимости. Правильно собранный игровой ПК не только обеспечивает комфортный геймплей в современных играх, но и. . .
Обновление сайта www.historian.b­y
Reglage 05.01.2025
Обещал подвести итоги 2024 года для сайта. Однако начну с того, что изменилось за неделю. Добавил краткий урок по последовательности действий при анализе вредоносных файлов и значительно улучшил урок. . .
Как использовать GraphQL в C# с HotChocolate
Programming 05.01.2025
GraphQL — это современный подход к разработке API, который позволяет клиентам запрашивать только те данные, которые им необходимы. Это делает взаимодействие с API более гибким и эффективным по. . .
Модель полного двоичного сумматора с помощью логических операций (python)
AlexSky-coder 04.01.2025
def binSum(x:list, y:list): s=^y] p=x and y for i in range(1,len(x)): s. append((x^y)^p) p=(x and y)or(p and (x or y)) return s x=list() y=list()
Это мы не проходили, это нам не задавали...(аси­­­­­­­­­­­­­­хро­н­н­ы­й счётчик с управляющим сигналом задержки).
Hrethgir 04.01.2025
Асинхронный счётчик на сумматорах (шестиразрядный по числу диодов на плате, но наверное разрядов будет больше - восемь или шестнадцать, а диоды на старшие), так как триггеры прошли тестирование и. . .
Руководство по созданию бота для Телеграм на Python
IT_Exp 04.01.2025
Боты для Телеграм представляют собой автоматизированные программы, которые выполняют различные задачи, взаимодействуя с пользователями через интерфейс мессенджера. В данной статье мы рассмотрим,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru