Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
 
Kukurudza
104 / 85 / 6
Регистрация: 29.08.2012
Сообщений: 539
29.06.2014, 19:15     Сравнение производных классов #1
Друзья!
Пусть у меня есть базовый класс 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 и прочую "лишнюю" инфу, но вот как супер контейнер узнает объект какого типа ему передали и в какой контейнер его пушнуть? собственно это такой же вопрос как и в первом посте.
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.06.2014, 19:15     Сравнение производных классов
Посмотрите здесь:

Наследование классов. Копирование производных классов C++
Создать массив в базовом абстрактном классе, и его передать функциям производных классов C++
C++ Ошибка при создании двумерного массива из объектов производных классов
C++ массив объектов разных производных классов
C++ Использование базовых и производных классов
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Vladimir.
155 / 155 / 10
Регистрация: 24.11.2009
Сообщений: 375
29.06.2014, 19:24     Сравнение производных классов #2
привести объект производного класса к базовому, сравнить приведенные объекты. dinamyc_cast вам в помощь
Kukurudza
104 / 85 / 6
Регистрация: 29.08.2012
Сообщений: 539
29.06.2014, 19:35  [ТС]     Сравнение производных классов #3
Хорошо, а если я хочу в будущем менять порядок следования объектов в контейнере?
Как я понял, вы предлагаете любой указатель приводить к указателю на базовый класс. Ок, привел. А как их потом сравнивать? Как понять что объект ЭТОГО типа "меньше" объекта вот ЭТОГО типа?
0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
29.06.2014, 19:37     Сравнение производных классов #4
А можно чуть больше контекста? Почему было принято решение именно так делать?

PS Мне как-то приходилось поддерживать гетерогенную очередь с приоритетами... Отделался добавлением в каждый класс свойства "Приоритет".
Kukurudza
104 / 85 / 6
Регистрация: 29.08.2012
Сообщений: 539
29.06.2014, 19:43  [ТС]     Сравнение производных классов #5
0x10, ну собственно ваш способ это и есть мой первый метод, верно?
Цитата Сообщение от 0x10 Посмотреть сообщение
А можно чуть больше контекста? Почему было принято решение именно так делать?
Пока еще не принято никакого решения. Есть только задача. Я думаю как бы это решить получше. В целом задача как в первом посте. Есть иерархия классов. Может быть создан объект любого из классов. И хочется хранить объекты всех типов в одном контейнере (ну или в нескольких, главное чтобы для пользователя было прозрачно, пушнул указатель в контейнер, а как он там хранится, по барабану). При этом я, например, хочу выводить весь контейнер в файлик, в заданном МНОЮ порядке. апример, сначала все объекты класса S, затем A, затем B и так далее.
0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
29.06.2014, 19:59     Сравнение производных классов #6
Цитата Сообщение от Kukurudza Посмотреть сообщение
ну собственно ваш способ это и есть мой первый метод, верно?
Я только не понял к чему в базовом классе какой-то enum.
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
29.06.2014, 20:07     Сравнение производных классов #7
Цитата Сообщение от Kukurudza Посмотреть сообщение
хочу выводить весь контейнер в файлик, в заданном МНОЮ порядке
Отсортировать указатели с использованием своей функции сравнения и вывести. Лучше не стоит использовать std::set, если требуется какая-то своя сортировка только для целей вывода в определенном порядке.
Kukurudza
104 / 85 / 6
Регистрация: 29.08.2012
Сообщений: 539
29.06.2014, 20:08  [ТС]     Сравнение производных классов #8
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
че нить такое?
Vladimir.
155 / 155 / 10
Регистрация: 24.11.2009
Сообщений: 375
29.06.2014, 20:09     Сравнение производных классов #9
Цитата Сообщение от 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;   
}
вывод:
Код
1B
3Ch1
3Ch2
3Ch3
0
1
0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
29.06.2014, 20:11     Сравнение производных классов #10
Kukurudza, ну ок. Только я бы еще этот приоритет сделал бы static - к чему дублировать его в каждом объекте.
Kukurudza
104 / 85 / 6
Регистрация: 29.08.2012
Сообщений: 539
29.06.2014, 20:13  [ТС]     Сравнение производных классов #11
Vladimir., ваш метод это собственно такой же что и мой. только один из них более наглядный (в зависимости от опыта кодера )
0x10, ну да, разумеется. всем плюсанул. спасибо.
0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
29.06.2014, 20:13     Сравнение производных классов #12
Vladimir., ну это хак, нецелевое использование возможностей языка. Нет гарантий, что при использовании другого компилятора будет полностью аналогично.
Voivoid
 Аватар для Voivoid
580 / 256 / 12
Регистрация: 31.03.2013
Сообщений: 1,284
29.06.2014, 20:21     Сравнение производных классов #13
Сообщение было отмечено автором темы, экспертом или модератором как ответ
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;
}
Kukurudza
104 / 85 / 6
Регистрация: 29.08.2012
Сообщений: 539
29.06.2014, 20:22  [ТС]     Сравнение производных классов #14
Voivoid, пожалуй, вы лучший
0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
29.06.2014, 20:24     Сравнение производных классов #15
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;
}
Иерархия жирнее, но дублирования уже нет.
Kukurudza
104 / 85 / 6
Регистрация: 29.08.2012
Сообщений: 539
29.06.2014, 20:27  [ТС]     Сравнение производных классов #16
0x10, хитрец
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
29.06.2014, 20:29     Сравнение производных классов #17

Не по теме:

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

Цитата Сообщение от 0x10 Посмотреть сообщение
А потом совесть замучила за то, что везде дублируется функция, отличающаяся не поведением, а только данными.
C++
1
std::string Name() const override { return "class A"; }
Kukurudza
104 / 85 / 6
Регистрация: 29.08.2012
Сообщений: 539
29.06.2014, 20:31  [ТС]     Сравнение производных классов #18
Tulosba, а что не так?
0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
29.06.2014, 20:31     Сравнение производных классов #19
Tulosba, все можно - главное, идея показана)
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.06.2014, 20:33     Сравнение производных классов
Еще ссылки по теме:

Структура наследования базовых/производных классов: error LNK 1104 C++
C++ Конструктор по умолчанию для производных классов
C++ Множественное наследование. Построение производных классов

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

Или воспользуйтесь поиском по форуму:
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
29.06.2014, 20:33     Сравнение производных классов #20
Цитата Сообщение от Kukurudza Посмотреть сообщение
а что не так?
Цитата Сообщение от 0x10 Посмотреть сообщение
C++
1
std::string Name() const override { return "class A"; }
Цитата Сообщение от Voivoid Посмотреть сообщение
C++
1
virtual int priority() const { return 2; }
Подход одинаковый (но для разных целей).
Yandex
Объявления
29.06.2014, 20:33     Сравнение производных классов
Ответ Создать тему
Опции темы

Текущее время: 14:55. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru