Где применить абстрактный класс и его свойства?

188
19 августа 2018, 05:40

Создаю приложение в Qt для работы с базой данных. По заданию необходимо использованием абстрактных классов. Например я хочу создать класс который связывается и работает с базой данных SQL и непосредственно при добавлении новой информации сразу добавляет информацию и в память и в TableWidget.

class DataBase{
  public:
    virtual void save() = 0; //Сохраняет информацию в SQL
    virtual void update() = 0; //Загружает из SQL таблицы и добавляет в память
    virtual void del(int index) = 0; //Удаляет какой-то index элемент таблицы
};

Ну и так далее, а затем создать какой-нить класс, который уже наследуется от DataBase

class StudentsData: public DataBase{
     private:
         vector<string> names; //имена студентов
         vector<string> lastnames; //фамилии студентов
         vector<int> marks; //оценки студентов
     public:
       //.. определить виртуальные функции .. //
};

То есть класс DataBase по сути абстрактный класс, который предназначен для работы с какой-то конкретной таблицей базы данных. Я просто совсем недавно начал пытаться разбираться с абстрактными классами и хотел понять, правильно я их смысл понимаю, потому что в интернете нашел единственный с точки зрения логики пример про абстрактный класс фигуры. И есть предложения как сделать проще и лучше?

Answer 1

Смысль абстрактного класса пропадает, если предусмотрена реализация только одного потомка. Что у вас не так?.. Скажу мое мнение:

Во первых virtual void delete(int) = 0; (тут излишне придать имя, поскольку обьект не используется). Индекс какого вектора из трех имеется ввиду?.. Вы будете удалять из имени, из фамилии или из оценок?.. По этой причине и для демонстрации преимуществ абстрактного( интерфейсным называют не спроста) класса, разделим понятие StudentsData на части. Именно такой подход позволяет разделять и властвовать...

Во вторых идентификатор delete это один из многих (скорее не очень многих) имен, который нельзя использовать в C++ в целях, отличных от той, для чего он предназначен...(специалистам прошу это предложение редактировать, если я неясно выразился)

class DataBase{
  public:
    virtual void save() = 0; 
    virtual void update() = 0; 
    virtual void del(int); 
    virtual bool size() const = 0;
};
class StudentsNames: public DataBase{
     private:
         vector<string> names; //имена студентов       
     public:
       //.. определить виртуальные функции .. del(int) можно не определять//
};
class StudentsLastNames: public DataBase{
     private:
         vector<string> lastnames; //фамилии студентов      
     public:
       //.. определить виртуальные функции .. del(int) можно не определять//
};
class StudentsMarks: public DataBase{
     private:
         vector<int> marks;  //оценки студентов     
     public:
       //.. определить виртуальные функции .. del(int) можно не определять//
};
//...    дальше можно добавить произвольное количество наследников,
//при этом перекомпиляция вашего кода  сведется к минимуму. 
void  implementation_code(DataBase* pb, int index)
{
    p->update();       // загружать
    if (p->size() > index) //если имеется больше index символов
    p->del(index);         //удалить (index + 1)- ый элемент
    p->save();         //сохранить результат
}

теперь можем функцию использовать для любого потомка, т.е. загружать, удалять какой то элемент и сохранить результат имени или фамилии или оценки

 StudentsNames name;
 StudentsLastNames last_name;
 StudentsMarks marks;

и если для всех трех потомков определен del(int)

 implementation_code(&name, 20);
 implementation_code(&last_name, 20);
 implementation_code(&marks, 5);

Вы вполне можете написать и подругому. Все зависит от целей и вкуса. Можете добавить любое количество потомков, и это не станет причиной перекомпиляции кода и легко будет управлять обьектами этих типов.

P.S. уверен, что многие расскажут лучше, я попытался помочь как могу...

READ ALSO
Не отображается код [закрыт]

Не отображается код [закрыт]

Во время отладки во второй части кода, visual начал серьезно тормозить, а программа повела себя не так как ожидалосьЯ прервал выполнение, но код...

186
Функция strtod() считывает только целую часть вещественного числа

Функция strtod() считывает только целую часть вещественного числа

Использую inih для парсинга ini файлаОбнаружилось то, что функция INIReader::GetReal(

167
Невозможно открыть вторую форму в Qt

Невозможно открыть вторую форму в Qt

При переходе на другую форму в Qt у меня возникает ошибка:

155
Правильная архитектура калькулятора

Правильная архитектура калькулятора

есть четыре поля, два любых заполняет пользователь, слушатель наблюдает за заполнением полей, два считаются на их основе по команде слушателяВопрос...

149