наследование от приватного класса QSqlTableModelPrivate

Наконец-то наш путь изучения Qt 4.8.1 привел нас к Q_D (приватным классам), которые скрыты (или защищены). Что там внутри и зачем так делается - немного обо всем.

Если вы пришли сюда значит скорее всего вам пришло в голову улучшить библиотеку Qt.

То есть вы хотите расширить функционал какого-то класса Qt под свои нужды.

А что так можно было? Оказывается да это возможно , не запрещено и т.д.

Примечание: на самом деле после удачного наследования от приватных классов в процесс их познания оказалось, что исходники Qt сделаны правильно и так наследоваться не надо, так как весь нужный функционал можно получить штатным наследованием от открытых классов Qt. Смотрите здесь Развитие Qt Sql

К примеру нас интерессует класс QSqlTableModel. Он делает запрос к содержанию одной таблицы, а мы хотим реализовать более сложный запрос по содержанию двух таблиц.

Назовем наш класс my_QSqlTableModel.

Исходники my_QSqlTableModel надо собирать вместе со всеми исходниками Qt, разместим код my_QSqlTableModel в той же папке, где и исходники QSqlTableModel.

Далее сделаем наследование my_QSqlTableModel:QSqlTableModel в стиле QSqlRelationalTableModel. То есть подглядим как сделано в QSqlRelationalTableModel::QSqlTableModel.

Уберем все лишнее, оставим только минимум для демонстрации новых возможностей.

Пример можно скачать ниже.

Иерархия скрыто создаваемых приватных классов:

фотка 1

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

ctor protect QAbstractItemModel::QAbstractItemModel d 0x29c96d8
ctor protect QSqlQueryModel::QSqlQueryModel d 0x29c96d8
ctor protect QSqlTableModel::QSqlTableModel d 0x29c96d8

Как видно у всех конструкторов указатель на приватный класс Q_D одинаковый. То есть по сути создается один наследник от всей цепочки родителей.

Но на самом деле с практической стороны нас больше интересует класс QSqlRelationalTableModel. Его можно унаследовать вместе с его приватным классом.

Как улучшить QSqlRelationalTableModel.

Есть важный нюанс наследник должен быть частью исходников библиотеки qt QSqlxxx и собираться вместе с исходниками Qt.

Файлы для скачивания

* пример класса унаследованного от QSqlTableModel , а также от приватного класса QSqlTableModelPrivate через _p.h файл [zip]
добавляем к исходникам Qt 4.8.1 шаблон наследования от QSqlTableModel

измененный QSqlRelationalTableModel чтобы от него можно было наследовать private класс QSqlRelationalTableModelClassPrivate [zip]
изменение исходников Qt 4.8.1, изменен QSqlRelationalTableModel, точнее определение приватного класса QSqlRelationalTableModelPrivate вынесено в _p.h файл