Страницы

Поиск по вопросам

пятница, 15 февраля 2019 г.

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

Создаю приложение в 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 names; //имена студентов vector lastnames; //фамилии студентов vector marks; //оценки студентов public: //.. определить виртуальные функции .. // };
То есть класс DataBase по сути абстрактный класс, который предназначен для работы с какой-то конкретной таблицей базы данных. Я просто совсем недавно начал пытаться разбираться с абстрактными классами и хотел понять, правильно я их смысл понимаю, потому что в интернете нашел единственный с точки зрения логики пример про абстрактный класс фигуры. И есть предложения как сделать проще и лучше?


Ответ

Смысль абстрактного класса пропадает, если предусмотрена реализация только одного потомка. Что у вас не так?.. Скажу мое мнение:
Во первых 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 names; //имена студентов public: //.. определить виртуальные функции .. del(int) можно не определять// }; class StudentsLastNames: public DataBase{ private: vector lastnames; //фамилии студентов public: //.. определить виртуальные функции .. del(int) можно не определять// }; class StudentsMarks: public DataBase{ private: vector 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. уверен, что многие расскажут лучше, я попытался помочь как могу...

Комментариев нет:

Отправить комментарий