#c #qt #vector #qwt
#c #qt #вектор #qwt
Вопрос:
У меня есть std::vector
заполненные QLabel
QwtSlider
указатели и, и я хотел бы удалить указатели, но не вектор.
Вот мой код:
QLabel *sliderSimuVarLabel;
std::vector<QLabel*> labelsSimuVarList;
std::vector<QwtSlider*> slidersSimuVarList;
int num = 3;
for (int i=0; i<numSimuVars; i){
sliderSimuVarLabel = new QLabel("Hello", Widg);
sliderSimuVarLabel->setFont(panelFont2);
labelsSimuVarList.push_back(new QLabelWidg));
labelsSimuVarList[i]->setFont(panelFont2);
slidersSimuVarList.push_back(new QwtSlider(Qt::Horizontal,Widg));
layoutSimuPanel->addWidget(sliderSimuVarLabel,i 7,0);
layoutSimuPanel->addWidget(slidersSimuVarList[i],i 7,1,1,5);
layoutSimuPanel->addWidget(labelsSimuVarList[i], i 7, 7);
}
Я не знаю, с помощью какого метода удалить указатели: clear()
? deleteLater()
? другие?
Комментарии:
1. Следите за обсуждением здесь: qt-project.org/forums/viewthread/43978
2. Обычно я устанавливаю родительский элемент и позволяю Qt обрабатывать удаление. Хотя это может быть проблемой, если родительский объект остается дольше, чем вы хотите, чтобы дочерние элементы.
3. Да, @drescherjm, это так. Я бы хотел, чтобы родительский элемент оставался дольше, чем дочерние элементы. Должен ли я создать дочерний QWidget родительского? Если да, то как удалить дочерний QWidget позже?
4. В этом случае вы должны быть в состоянии сделать то, что сказал @vahancho в своем ответе.
5. Я применил решение @vahnancho и сработал! спасибо всем!
Ответ №1:
Используйте std::unique_ptr
. В этом случае вам не нужно ничего делать, чтобы впоследствии очистить объекты, и это безопасно в случае таких вещей, как исключение или досрочное возвращение. Никогда ничего не delete
делайте самостоятельно, так как это ужасно небезопасно. Я считаю, что Qt также предоставляет некоторые собственные интеллектуальные указатели, а Boost также предоставляет shared_ptr
и другие для использования.
Комментарии:
1. -1 потому что это ужасно расплывчато и неопределенно неверно. Для использования
std::unique_ptr
или эквивалентаQScopedPointer
в контейнере требуется C 11 и контейнер, поддерживающий семантику перемещения, поскольку интеллектуальные указатели не могут быть ни назначены, ни скопированы. С C 11 вам даже не нужно использовать astd::unique_ptr
. Вы можете просто поместитьQObject
экземпляры, не подлежащие копированию, в astd::list
. Единственным решением, отличным от C 11, является использованиеstd::shared_ptr
orQSharedPointer
со всеми накладными расходами на блокировку памяти, которые это влечет за собой (на самом деле он не является общим, за исключением короткого времени, когда вещи перемещаются).2. Единственным «реальным» решением этой проблемы было бы современное
QPtrList
переопределение иQPtrVector
из Qt 3, возможно, в качестве адаптера контейнера. Я уверен, что что-то подобное должно где-то существовать… ах да, библиотека контейнеров указателей Boost .3. @KubaOber Ты говоришь так, как будто в наши дни трудно получить в свои руки реализацию C 11.
4. @KubaOber: Это текущий стандарт и
unique_ptr
одна из самых ранних реализованных функций для всех основных компиляторов. К этому моменту даже Microsoft поддерживала его годами. Кроме того, перестаньте плакать о накладных расходах на блокировкуshared_ptr
, никого не волнует, насколько быстр код OP, когда он выдает исключение и пропускает все свои объекты, и вы даже не знаете, что он находится на горячем пути, который в любом случае будет иметь какое-либо отношение к производительности.5. Существует простое решение проблем, связанных с ужасными контейнерами Qt: не используйте контейнеры Qt.
Ответ №2:
Чтобы удалить объекты (указатели) из вашего вектора и удалить их, вы можете:
// Remove elements from the back
while (!labelsSimuVarList.empty()) {
delete labelsSimuVarList.back();
labelsSimuVarList.pop_back();
}
Комментарии:
1. Имеет ли это то же значение
QVector::clear()
?2. @Tay2510 Очистка вектора освободит указатели, а не объекты. Если вы хотите очистить содержимое контейнера Qt, используйте
qDeleteAll
3.
qDeleteAll
принимает пару итераторов и вообще не привязан к контейнерам Qt.4. -1 за ужасное ручное управление памятью. Пожалуйста, умные указатели.