Сортировка объектов и полиморфизм - PullRequest
1 голос
/ 17 марта 2010

Предположим, у меня есть класс А.

А В и С являются потомками А.

Класс A имеет общий алгоритм для сортировки массивов типа A, так что я могу использовать его для B и C, не переписывая алгоритм для каждого.

В алгоритме иногда приходится менять местами. Проблема в том, что я могу видеть только объекты типа А, и если я это сделаю:

A aux = array[i]
array[i] = array[j]
array[j] = aux

Мне кажется, у меня проблема. Поскольку массив [i], возможно, имеет тип B, а вспомогательный тип A, поэтому я думаю, что теряю информацию.

Я уверен, что вы понимаете эту ситуацию ... как я могу отсортировать общий массив объектов, используя алгоритм метода отца?

Редактировать: исходный массив статичен.

Edit2: Так что невозможно иметь: A :: sort (A array []); И делать то, что я хочу?, Не могу поменяться.

Единственный способ иметь массив ссылок? * Массив []?

Ответы [ 3 ]

8 голосов
/ 17 марта 2010

Полиморфные объекты ссылаются на указатели или ссылки (или оболочки-указатели). Замена указателей достаточно тогда. На самом деле, вы должны иметь возможность использовать std::sort или std::stable_sort с подходящим предикатом:

// 'A' defines 'float getSortKey()'

bool mypred(B* first, B* second) {
   return first->getSortKey() < second->getSortKey();
}

std::vector<B*> them;
std::sort(them.begin,them.end(),mypred);

Эта стратегия позволяет избежать нарезки объектов.

0 голосов
/ 18 марта 2010

У меня есть идея. Ваш тег 'полиморфизм' вводит в заблуждение, если вы хотите хранить по значениям. Как насчет простого перезаписи значения ключа в A объектах класса, которое используется A::sort?

struct A
{
    int key;
    A(int _key) : key(_key) {}
    static sort(A array[]); // uses 'key'
};

struct B : public A
{
    B() : A( generate_B_key() ) {}
};

struct C : public A
{
    C() : A( generate_C_key() ) {}
};
0 голосов
/ 18 марта 2010

@ ritmbo, до тех пор, пока вы не знакомы с механизмами полиморфизма, требуется объяснение, чтобы уточнить ответ Александра.

Почему вы должны изменить std::vector<A> на std::vector<A*>?

Вы хотите иметь коллекцию объектов базового класса, поэтому для их сортировки необходимо переместить ответственность за сравнение объектов с класса A на B и C. Для этого в ООП вы используете виртуальные функции. Они связаны с объектом как виртуальная таблица . Если вы разыгрываете B* на A*, например, A* a = new B;, vtable из a перезаписывается методами new B. Но если вы разыгрываете B на A, например, A a = B(), указатели методов не копируются в a s vtable .

Короче говоря, вы не будете переносить ответственность за сравнение в класс B и C без использования указателей (или ссылок, но это сложнее поддерживать).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...