Здравствуйте, недавано познакомился с Qt, но визникли некоторые проблемы по поводу использования умных указателей вместес QTableView, вот пример кода:
MainFormSettings::MainFormSettings(Ui::MainForm* mainForm) {
ui = mainForm;
administratorsService = new AdministratorsService;
modelAdministrators = new QStandardItemModel;
QStringList headers;
headers.append("Логин");
headers.append("Пароль");
modelAdministrators->setHorizontalHeaderLabels(headers);
ui->tableAdministrators->setModel(modelAdministrators);
QMap<QString, QString> administrators = administratorsService->getAllAdministrators();
size_t row = 0;
for (auto it = administrators.begin(); it != administrators.end(); it++) {
QString login = it.key();
QString password = it.value();
QStandardItem* itemLogin = new QStandardItem(login);
modelAdministrators->setItem(row, 0, itemLogin);
QStandardItem* itemPassword = new QStandardItem(password);
modelAdministrators->setItem(row, 1, itemPassword);
row++;
}
}
Так все прекрасно работает. Как видно из кода заполняю таблицу администраторов(лоиг и пароль) из базы данных, но потом при перезагрузки таблицы новыйми данными память же придется освободить, в связи с этим решил воспользоваться умными указателями:
MainFormSettings::MainFormSettings(Ui::MainForm* mainForm) {
ui = mainForm;
administratorsService = new AdministratorsService;
modelAdministrators = new QStandardItemModel;
QStringList headers;
headers.append("Логин");
headers.append("Пароль");
modelAdministrators->setHorizontalHeaderLabels(headers);
ui->tableAdministrators->setModel(modelAdministrators);
QMap<QString, QString> administrators = administratorsService->getAllAdministrators();
size_t row = 0;
for (auto it = administrators.begin(); it != administrators.end(); it++) {
QString login = it.key();
QString password = it.value();
std::unique_ptr<QStandardItem> itemLogin = std::make_unique<QStandardItem>(login);
modelAdministrators->setItem(row, 0, itemLogin.get());
std::unique_ptr<QStandardItem> itemPassword = std::make_unique<QStandardItem>(password);
modelAdministrators->setItem(row, 1, itemPassword.get());
row++;
}
}
Но когда я использую это, просто в таблицу ничего не выводится, по видимому память освобождается... Может кто-ниубдь подскажет в чем проблема и способ ее решения? Заранее спасибо
Используемый вами тип QStandardItemModel сам освободит в своем деструкторе все лежащие в нем объекты когда придет время; дополнительно освобождать что бы то ни было не только бесполезно, но и ошибочно.
Использовать unique_ptr для хранения промежуточных объектов можно - но только в более сложных случаях, когда вы не сразу передаете владение ими в другой класс. Для этого можно использовать метод release:
std::unique_ptr<QStandardItem> itemLogin = std::make_unique<QStandardItem>(login);
// ...
modelAdministrators->setItem(row, 0, itemLogin.release());
Но в вашем случае это избыточно, ведь между созданием объекта и добавлением его в modelAdministrators нет никакого лишнего кода.
Где и правда следует применять умные указатели - так это в вашем классе, для того чтобы автоматически освободить QStandardItemModel:
private:
std::unique_ptr<QStandardItemModel> modelAdministrators;
В данном случае Вам не нужны умные указатели: когда вы добавляете QStandardItem в модель, то уже модель отвечает за удаление своих элементов.
В случае с std::unique_ptr, вы добавляете в модель указатель на данные, затем область видимости std::unique_ptr заканчивается и указатель удаляется, модель в с свою очередь видит что элемент удален и по-этому не использует его для отображения.
Qt и стандартные умные указатели обычно не совместимы. В данном случае метод setItem принимает владение объектом, на который указывает переданный указатель. В других случаях могут применяться умные указатели qt.
Сборка персонального компьютера от Artline: умный выбор для современных пользователей