-1

I have a std::vector filled up with QLabel and QwtSlider pointers and I would like to delete the pointers but not the vector.

Here my code:

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);
}

I don’t know with which method delete the pointers: clear()? deleteLater()? others?

Jerry YY Rain
  • 4,134
  • 7
  • 35
  • 52
Simu
  • 11
  • 3
  • Follow the discussion here : http://qt-project.org/forums/viewthread/43978/ – Simu Jun 19 '14 at 14:37
  • I usually set the parent and let Qt handle the deletion. Although this may be a problem if the parent object stays around longer than you want the children. – drescherjm Jun 19 '14 at 14:56
  • Yes @drescherjm, this is the case. I would like that the parent stays longer than the children. Should I create a child QWidget of the parent? If yes, how delete the child QWidget later? – Simu Jun 19 '14 at 14:59
  • In that case you should be able to do what @vahancho said in his answer. – drescherjm Jun 19 '14 at 15:05
  • I applied the @vahnancho solution and worked! thank you to all! – Simu Jun 19 '14 at 15:19

2 Answers2

5

Use a std::unique_ptr. In this case you do not have to do anything to clear up the objects afterwards, and it's safe in the case of things like exception or early return. Do not ever delete anything yourself, as it is terribly unsafe to do so. I believe that Qt also provides some smart pointers of its own, and Boost also provides shared_ptr and others for you to use.

Puppy
  • 144,682
  • 38
  • 256
  • 465
  • 2
    -1 because it's awfully vague and vaguely incorrect. To use `std::unique_ptr` or the equivalent `QScopedPointer` in a container requires C++11 and a container that supports move semantics, since the smart pointers are not assignable nor copyable. With C++11, you don't even need to use a `std::unique_ptr`. You can simply emplace the non-copyable `QObject` instances in a `std::list`. The only non-C++11 solution is to use `std::shared_ptr` or `QSharedPointer`, with all the memory locking overhead it entails (it's not really shared except for short time when things are moved around). – Kuba hasn't forgotten Monica Jun 19 '14 at 19:07
  • 1
    The only "real" solution to this problem would be a modern reimplementation of `QPtrList` and `QPtrVector` from Qt 3, perhaps as a container adapter. I'm sure something like that must exist somewhere... ah yes, the [Boost pointer container](http://www.boost.org/doc/libs/1_55_0/libs/ptr_container/doc/ptr_container.html) library. – Kuba hasn't forgotten Monica Jun 19 '14 at 19:15
  • 1
    @KubaOber, doh, what. I mean, what. – Griwes Jun 19 '14 at 19:18
  • 4
    @KubaOber You're talking like it's hard to get your hands on a C++11 implementation these days. – Etienne de Martel Jun 19 '14 at 19:19
  • 1
    @KubaOber, I mean: OH NOES IT REQUIRES C++11 A.K.A. THE THREE YEARS OLD (NOT TO MENTION CURRENT) STANDARD. – Griwes Jun 19 '14 at 19:19
  • 2
    @KubaOber: It is the current Standard and `unique_ptr` is one of the earliest implemented features for all major compilers. Even Microsoft has supported it for years by this point. Also, quit crying about the locking overhead of `shared_ptr`, nobody's gonna care how fast the OP's code is when he throws an exception and leaks all his objects, and you don't even know he's in a hot path that will have any performance relevance anyway. – Puppy Jun 19 '14 at 19:22
  • @KubaOber Oh no the performance of my UI-code-that-mostly-sits-idle will tank if I use shared_ptr. Modern implementations use atomics for maintaining the reference count so 'locking overhead' is non-existent anyway. – Cat Plus Plus Jun 19 '14 at 19:28
  • Again, you're vague since you can't just stuff `unique_ptr` into any container. It won't compile. It will compile if you use it with `std::vector` and `std::list`, but won't with, say, `QVector` or `QList`. That's because `std::unique_ptr` is not copyable nor copy-constructible. I don't know if it works with `std::` containers due to their move semantics or due to specializations for `unique_ptr`. – Kuba hasn't forgotten Monica Jun 19 '14 at 19:28
  • 2
    There's a simple solution to woes related to Qt containers being terrible: don't use Qt containers. – Cat Plus Plus Jun 19 '14 at 19:29
  • @KubaOber Standard containers are move aware, that's why they allow non copyable types. – Etienne de Martel Jun 19 '14 at 19:31
  • @KubaOber: It works with all C++11-compliant containers. Also, there's really no reason to use QVector or QList. – Puppy Jun 19 '14 at 19:32
  • @DeadMG Except if you wish to interoperate with Qt, and then your code gets sprinkled with conversions all over the place. Never mind that the working set grows, as oft-running code is using two sets of containers. The boost-based solution isn't any good in this respect, I admit, and I presume that heap-use-wise the C++ and Qt containers are comparable. – Kuba hasn't forgotten Monica Jun 19 '14 at 20:07
  • 1
    In any case, I really don't see why bother with `std::unique_ptr` in C++11. If you have a `std::list`, you can simply emplace the instances, no need for explicit pointers at all. That's IMHO how it should be done in C++11. – Kuba hasn't forgotten Monica Jun 19 '14 at 20:11
-6

To remove objects (pointers) from your vector and delete them you can:

// Remove elements from the back
while (!labelsSimuVarList.empty()) {
    delete labelsSimuVarList.back();
    labelsSimuVarList.pop_back();
}
vahancho
  • 20,808
  • 3
  • 47
  • 55