Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 29.11.2012, 17:07   #1
Frants
Пользователь
 
Регистрация: 12.01.2012
Сообщений: 19
По умолчанию Сортировка массива указателей на абстрактный базовый класс

Я создал абстрактный базовый класс (с названием Base) и два производных класса (с названиями Two и Three). После инициализации объектов производных классов каждый из этих объектов имеет два данных-члена: string и double.
Вопрос: как можно организовать сортировку всех созданных объектов (и объектов Two, и объектов Three)?

Первое мое действие - я создаю массив указателей на АБК Base и помещаю в него все имеющиеся объекты производных классов.

А дальше как сделать не знаю... Нужно организовать сортировку по данному-члену double по убыванию. Если же значения double совпадают - отсортировать по значению string.
Frants вне форума Ответить с цитированием
Старый 29.11.2012, 17:32   #2
Granus
С++
Форумчанин
 
Аватар для Granus
 
Регистрация: 22.09.2008
Сообщений: 791
По умолчанию

Чтобы отсортировать по этим полям, нужно чтобы базовый класс о них знал. Т.е. либо объявите их в базовом, либо сделайте виртуальные методы getDouble() и getString(), например.
Форматируйте код, будьте людьми.
Granus вне форума Ответить с цитированием
Старый 29.11.2012, 17:54   #3
Frants
Пользователь
 
Регистрация: 12.01.2012
Сообщений: 19
По умолчанию

Цитата:
Сообщение от Granus Посмотреть сообщение
Чтобы отсортировать по этим полям, нужно чтобы базовый класс о них знал. Т.е. либо объявите их в базовом, либо сделайте виртуальные методы getDouble() и getString(), например.
Базовый класс знает о них, в нем они изначально и содержатся:

Код:
//Base class
class Base
{
    private:
              string name;
    protected:
              double totalNumber;
    public:
              Base(const string & n = "Unknown");
              virtual void calc() = 0;
              void show();
              virtual ~Base(){}
};

//Введенное при инициализации объекта число умножается на 2
class Two : public Base
{
      private:
              double userNumber;
      public:
              Two(const string & n = "Unknown", double userN = 0.0);
              virtual void calc();
              
};

//Введенное при инициализации объекта число умножается на 3
class Three : public Base
{
      private:
              double userNumber;
      public:
              Three(const string & n = "Unknown", double userN = 0.0);
              virtual void calc();
};
Frants вне форума Ответить с цитированием
Старый 29.11.2012, 17:57   #4
Granus
С++
Форумчанин
 
Аватар для Granus
 
Регистрация: 22.09.2008
Сообщений: 791
По умолчанию

Здесь про string не знают потомки, потому что он в private. И зачем вы переопределяете double'ы в потомках? Опишите более четко, что это и чего Вы хотите.
Форматируйте код, будьте людьми.
Granus вне форума Ответить с цитированием
Старый 29.11.2012, 18:19   #5
Frants
Пользователь
 
Регистрация: 12.01.2012
Сообщений: 19
По умолчанию

Цитата:
Сообщение от Granus Посмотреть сообщение
Здесь про string не знают потомки, потому что он в private. И зачем вы переопределяете double'ы в потомках? Опишите более четко, что это и чего Вы хотите.
Я учусь только, поймите...

1) string перенесу в protected.
2) double'ы я вроде не переопределяю... В базовом классе имя ему totalNumber, а в производных userNumber. Но я понял свою ошибку - можно обойтись лишь тем double'ом, который находится в базовом классе.

Задача такая: создать три класса (базовый класс и два производных). В базовом классе описать абстрактный метод (в моем примере это метод calc()) для расчета этого самого double'а totalNumber, который находится в базовом классе. Пользователь должен ввести имя и число при инициализации объекта. Это число в свою очередь умножается на 2 в классе Two, и на 3 в классе Three (в оригинале математические действия сложнее, но суть не в них, поэтому упростил), затем полученное число присваивается totalNumber'у. В конце нужно отсортировать все объекты и вывести на экран в порядке убывания этого самого totalNumber.
Объекты, у которых totalNumber совпадает отсортировать по string-значению.
Frants вне форума Ответить с цитированием
Старый 29.11.2012, 18:27   #6
Granus
С++
Форумчанин
 
Аватар для Granus
 
Регистрация: 22.09.2008
Сообщений: 791
По умолчанию

То есть при инициализации записывается число в userNumber, при вызове calc() оно обрабатывается и записывается в totalNumber, так?
В таком случае с double'ами все нормально. Создаете массив (или список, как уобнее) указателей на Base, пользователь заполняет значения, потом (или срау при записи) для всех вы вызываете calc(), потом сортируете.
Форматируйте код, будьте людьми.
Granus вне форума Ответить с цитированием
Старый 29.11.2012, 18:34   #7
Frants
Пользователь
 
Регистрация: 12.01.2012
Сообщений: 19
По умолчанию

Цитата:
Сообщение от Granus Посмотреть сообщение
То есть при инициализации записывается число в userNumber, при вызове calc() оно обрабатывается и записывается в totalNumber, так?
Да!
Цитата:
Сообщение от Granus Посмотреть сообщение
В таком случае с double'ами все нормально. Создаете массив (или список, как уобнее) указателей на Base, пользователь заполняет значения, потом (или срау при записи) для всех вы вызываете calc(), потом сортируете.
Так именно это я и спросил изначально, как отсортировать?) Надо ведь как-то функцию sort изменить? vector использовать? Скажите примерный план действий, а дальше сам попробую.
Frants вне форума Ответить с цитированием
Старый 29.11.2012, 18:39   #8
Granus
С++
Форумчанин
 
Аватар для Granus
 
Регистрация: 22.09.2008
Сообщений: 791
По умолчанию

А, не понял сразу, в чем проблема)
Ну да, например, vector. Стандартный std::sort подойдет, только ему компаратор нужен. Напишите функцию (например, compare), которая будет принимать два указателя на Base, сравнивать (как Вы сказали, сначала по значению, потом, если они совпадают, по имени), и возвращать результат типа bool. И вызывайте сортировку
Код:
std::sort(data.begin(), data.end(), compare);
Форматируйте код, будьте людьми.
Granus вне форума Ответить с цитированием
Старый 29.11.2012, 19:14   #9
Frants
Пользователь
 
Регистрация: 12.01.2012
Сообщений: 19
По умолчанию

Не знаю что я делаю не так, но:

Я создал такую функцию:
Код:
bool Base::compare(const Base & r1, const Base & r2)
{
    if (r1.totalNumber < r2.totalNumber)
        return true;
    else if (r1.totalNumber == r2.totalNumber && r1.name < r2.name)
        return true;
    else
        return false;
}
И объявил ее прототип в базовом классе в public:
Код:
bool compare(const Base & r1, const Base & r2);
Начал пробовать...
Код:
#include <iostream>
#include <string>
#include <vector>
#include "final_class.h"
#include "definitions.h"

using namespace std;

int main()
{
    Two number_1("Mike",3);
    Three number_2("Joe",3);
    
    vector<Base*>people;
    people.push_back(&number_1);
    people.push_back(&number_2);
    sort(people.begin(), people.end(),compare);
    
    system("PAUSE");
    return 0;   
}
Но выдает ошибку:`compare' undeclared (first use this function)

Как же compare не объявлена, когда она очень даже объявлена? Понимаю, что мой косяк где-то, но где?
Frants вне форума Ответить с цитированием
Старый 29.11.2012, 19:25   #10
Granus
С++
Форумчанин
 
Аватар для Granus
 
Регистрация: 22.09.2008
Сообщений: 791
По умолчанию

Она не объявлена в глобальной области видимости, только в классе Base. Более того, это нестатический метод класса, и ему для вызова нужен объект. То есть Вы не можете написать Base::compare(x, y), нужен объект: base.compare(x, y). Если уж Вам хочется, чтобы функция была внутри класса Base, сделайте ее статической (модификатор static). И передавайте не ссылку, а указатель, все-таки вы сортируете массив именно указателей. А в sort передавайте Base::compare.
Форматируйте код, будьте людьми.
Granus вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Создать абстрактный базовый класс C++ MicRaiS Общие вопросы C/C++ 3 11.06.2012 13:14
Правильна ли такая реализация списка из указателей на базовый класс? Archet Общие вопросы C/C++ 14 18.01.2012 16:08
Абстрактный базовый класс(задача) friman134 Общие вопросы C/C++ 2 17.12.2011 21:51
Сортировка массива указателей Джед Общие вопросы C/C++ 3 02.06.2009 14:18