Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.72/25: Рейтинг темы: голосов - 25, средняя оценка - 4.72
106 / 87 / 13
Регистрация: 29.08.2012
Сообщений: 538

Сравнение производных классов

29.06.2014, 19:15. Показов 5632. Ответов 24
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Друзья!
Пусть у меня есть базовый класс S. У него есть два наследника A и B. Как мне скидывать, например в set, указатели (шаредпэтэры например) на объекты классов A и B так, чтобы сначала шли объеты класса A, затем объекты класса B?
Понятно как сравнивать объекты класса только A или только B между собой, а как сравнивать объекты классов A и B между собой? Потенциально может быть и так что у A и B тоже будут наследники, например Aa, Ab, Ba и Bb. И тогда надо будет сравнивать все объекты между собой (S, A, B, Aa, Ab, Ba, Bb). Как такое делается?

Добавлено через 11 минут
У мея есть два варианта:
1. В класс S добавить enum, и в зависимости что за объект объявляем, выставлять IDшник этого объекта. таким образом у каждого обекта будет свой IDшник (возможно они будут повторяться, если например будет несколько объектов одного класса). Ну собственно сравнивать объекты по этому ID. Вроде норм, но кажется что этот ID это какой-то костыль
2. Сделать один супер контейнер, в котором указатели на контейнеры, каждый из которых хранит объекты только своего типа. Этот вариант мне нравится - не нужно хранить никакие ID и прочую "лишнюю" инфу, но вот как супер контейнер узнает объект какого типа ему передали и в какой контейнер его пушнуть? собственно это такой же вопрос как и в первом посте.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
29.06.2014, 19:15
Ответы с готовыми решениями:

Наследование классов. Копирование производных классов
Здравствуйте всем, у меня такой вопрос: написал код #include "stdafx.h" class A //Создаем класс А { int mA; ...

Использование базовых и производных классов
Не могу решить задачу с классами помогите с решением. Создать класс String – строка. Определить функции присваивания одной строки...

Файлы и объекты производных классов
Вопрос следующий: имеется два класса, базовый и производный. В файл бинарно записывается объект производного класса через указатель на...

24
377 / 228 / 79
Регистрация: 24.11.2009
Сообщений: 695
29.06.2014, 19:24
привести объект производного класса к базовому, сравнить приведенные объекты. dinamyc_cast вам в помощь
0
106 / 87 / 13
Регистрация: 29.08.2012
Сообщений: 538
29.06.2014, 19:35  [ТС]
Хорошо, а если я хочу в будущем менять порядок следования объектов в контейнере?
Как я понял, вы предлагаете любой указатель приводить к указателю на базовый класс. Ок, привел. А как их потом сравнивать? Как понять что объект ЭТОГО типа "меньше" объекта вот ЭТОГО типа?
0
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
29.06.2014, 19:37
А можно чуть больше контекста? Почему было принято решение именно так делать?

PS Мне как-то приходилось поддерживать гетерогенную очередь с приоритетами... Отделался добавлением в каждый класс свойства "Приоритет".
1
106 / 87 / 13
Регистрация: 29.08.2012
Сообщений: 538
29.06.2014, 19:43  [ТС]
0x10, ну собственно ваш способ это и есть мой первый метод, верно?
Цитата Сообщение от 0x10 Посмотреть сообщение
А можно чуть больше контекста? Почему было принято решение именно так делать?
Пока еще не принято никакого решения. Есть только задача. Я думаю как бы это решить получше. В целом задача как в первом посте. Есть иерархия классов. Может быть создан объект любого из классов. И хочется хранить объекты всех типов в одном контейнере (ну или в нескольких, главное чтобы для пользователя было прозрачно, пушнул указатель в контейнер, а как он там хранится, по барабану). При этом я, например, хочу выводить весь контейнер в файлик, в заданном МНОЮ порядке. апример, сначала все объекты класса S, затем A, затем B и так далее.
0
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
29.06.2014, 19:59
Цитата Сообщение от Kukurudza Посмотреть сообщение
ну собственно ваш способ это и есть мой первый метод, верно?
Я только не понял к чему в базовом классе какой-то enum.
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
29.06.2014, 20:07
Цитата Сообщение от Kukurudza Посмотреть сообщение
хочу выводить весь контейнер в файлик, в заданном МНОЮ порядке
Отсортировать указатели с использованием своей функции сравнения и вывести. Лучше не стоит использовать std::set, если требуется какая-то своя сортировка только для целей вывода в определенном порядке.
1
106 / 87 / 13
Регистрация: 29.08.2012
Сообщений: 538
29.06.2014, 20:08  [ТС]
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
enum enm {
    S_ENM = 0,
    A_ENM = 1,
};
 
class S {
    const enm ID_;
 
public:
    explicit S() : ID_(S_ENM) {
    }
 
    explicit S(const enm ID) : ID_(ID) {
    }
 
    //  компаратор по ID_
};
 
class A : public S {
public:
    explicit A() : S(A_ENM) {
    }
};
при добавлении нового наследника, просто добавляем его ID в enum
че нить такое?
0
377 / 228 / 79
Регистрация: 24.11.2009
Сообщений: 695
29.06.2014, 20:09
Цитата Сообщение от Kukurudza Посмотреть сообщение
При этом я, например, хочу выводить весь контейнер в файлик, в заданном МНОЮ порядке. апример, сначала все объекты класса S, затем A, затем B и так далее.
простите, не правильно вас понял вначале.
Посмотрите:
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
#include <iostream>
#include <typeinfo>
#include <memory>
 
class B {
public:
   virtual void foo() {}
};
 
class Ch1 : public B {};
class Ch2 : public B {};
class Ch3 : public Ch1 {};
 
using namespace std;
int main() {
   shared_ptr<B> ptr1(new B);
   shared_ptr<B> ptr2(new Ch1);
   shared_ptr<B> ptr3(new Ch2);
   shared_ptr<B> ptr4(new Ch3);
   
   cout << typeid( *ptr1 ).name() << endl;   
   cout << typeid( *ptr2 ).name() << endl;   
   cout << typeid( *ptr3 ).name() << endl;   
   cout << typeid( *ptr4 ).name() << endl;   
   cout<< typeid( *ptr4 ).before(typeid( *ptr1))<<endl;
   cout<< typeid( *ptr2 ).before(typeid( *ptr4))<<endl;   
}
вывод:
Code
1
2
3
4
5
6
1B
3Ch1
3Ch2
3Ch3
0
1
1
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
29.06.2014, 20:11
Kukurudza, ну ок. Только я бы еще этот приоритет сделал бы static - к чему дублировать его в каждом объекте.
1
106 / 87 / 13
Регистрация: 29.08.2012
Сообщений: 538
29.06.2014, 20:13  [ТС]
Vladimir., ваш метод это собственно такой же что и мой. только один из них более наглядный (в зависимости от опыта кодера )
0x10, ну да, разумеется. всем плюсанул. спасибо.
0
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
29.06.2014, 20:13
Vladimir., ну это хак, нецелевое использование возможностей языка. Нет гарантий, что при использовании другого компилятора будет полностью аналогично.
0
 Аватар для Voivoid
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
29.06.2014, 20:21
Лучший ответ Сообщение было отмечено Kukurudza как решение

Решение

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
class S {
public:
  virtual int priority() const {
    return 1;
  }
 
  struct comparer {
    bool operator()( const S* s1, const S* s2 ) const {
      return s1->priority() < s2->priority();
    }
  };
};
 
class B : public S {
public:
  virtual int priority() const {
    return 2;
  }
};
 
class C : public S {
public:
  virtual int priority() const {
    return 3;
  }
};
 
int main() {
  std::set<S*, S::comparer> objs;
  objs.insert( new B );
 
  return 0;
}
0
106 / 87 / 13
Регистрация: 29.08.2012
Сообщений: 538
29.06.2014, 20:22  [ТС]
Voivoid, пожалуй, вы лучший
0
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
29.06.2014, 20:24
Voivoid, у меня когда-то примерно так и было реализовано) А потом совесть замучила за то, что везде дублируется функция, отличающаяся не поведением, а только данными.
В итоге получилось что-то такое:
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
#include <algorithm>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
 
class BasePriority {
public:
    virtual int GetPriority() const = 0;
    virtual std::string Name() const = 0;
};
 
template <int p>
class Priority : public BasePriority {
public:
    int GetPriority() const override { return priority_; }
private:
    static const int priority_ = p;
};
 
class A : public Priority<2> {
public:
    std::string Name() const override {
        return "class A";
    }
};
 
class B : public Priority<1> {
public:
    std::string Name() const override {
        return "class B";
    }
};
 
typedef std::shared_ptr<BasePriority> BasePriorityPtr;
typedef std::vector<BasePriorityPtr> BasePtrContainer;
 
int main() {
    struct PriorityComparator {
        bool operator()(const BasePriorityPtr& lhs,
                const BasePriorityPtr& rhs) const {
            return lhs->GetPriority() < rhs->GetPriority();
        }
    };
        
    BasePtrContainer container {
        std::make_shared<B>(),
        std::make_shared<A>(),
        std::make_shared<B>(),
        std::make_shared<B>()
    };
    
    std::sort(container.begin(), container.end(), PriorityComparator());
    
    for (const auto& item : container) {
        std::cout << item->Name() << std::endl;
    }
    
    return 0;
}
Иерархия жирнее, но дублирования уже нет.
1
106 / 87 / 13
Регистрация: 29.08.2012
Сообщений: 538
29.06.2014, 20:27  [ТС]
0x10, хитрец
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
29.06.2014, 20:29

Не по теме:

0x10, а чего компаратор не ввиде лямбды, раз уж C++11? :)

Цитата Сообщение от 0x10 Посмотреть сообщение
А потом совесть замучила за то, что везде дублируется функция, отличающаяся не поведением, а только данными.
C++
1
std::string Name() const override { return "class A"; }
0
106 / 87 / 13
Регистрация: 29.08.2012
Сообщений: 538
29.06.2014, 20:31  [ТС]
Tulosba, а что не так?
0
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
29.06.2014, 20:31
Tulosba, все можно - главное, идея показана)
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
29.06.2014, 20:33
Цитата Сообщение от Kukurudza Посмотреть сообщение
а что не так?
Цитата Сообщение от 0x10 Посмотреть сообщение
C++
1
std::string Name() const override { return "class A"; }
Цитата Сообщение от Voivoid Посмотреть сообщение
C++
1
virtual int priority() const { return 2; }
Подход одинаковый (но для разных целей).
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
29.06.2014, 20:33
Помогаю со студенческими работами здесь

Массив объектов разных производных классов
Задача такая: базовый класс - фигура, производные классы - круг, треугольник и т.п. Пользователь выбирает, какие фигуры будут на экране и...

Функция создающая объекты производных классов
Функция получает входной параметр - целое число. Если оно равно 0, создается новый объект - окружность, если равно 3 - создается...

Множественное наследование. Построение производных классов
Необходимо построить иерархию классов согласно схемы наследования. Каждый класс должен содержать инициализирующий конструктор и функцию...

Конструктор по умолчанию для производных классов
Допустим, имеется код: class abstr_emp { private: string fname; // abstr_emp's first name string lname; //...

Конструктор копирования производных классов: для чего это нужно?
Доброго времени суток! #ifndef EMP_H #define EMP_H #include &lt;iostream&gt; #include &lt;string&gt; class abstr_emp {


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru