Hi, I am the one that introduced this “problem”.
This was done because, as the commit says, to avoid having to deal with raw pointers, and its deletion, which was actually not happening, creating a potential memory leak.
The fact that a class has an unique_ptr in it will make it inherently non-copyable.
As already mentioned, the most common way to solve the issue about putting these kind of objects in a vector is to use emplace and move but I dont like this method cause you can not use std::vector::resize
for example.
I prefer to use std::vector<unique_ptr<SomeClass> >
or std::vector<shared_ptr<SomeClass> >
depending on the use I will give to these objects, although I tend to default to unique.
There are some other classes in of that can give you similar problems, like any class that has an ofEventListener
or ofEventListeners
instance in it, which is solved in the same way. (No, there is no typo, ofEventListener
and ofEventListeners
are different classes, where the latter is a collection of the former.
The following is how to properly use a collection of ofxPanel
#pragma once
#include "ofMain.h"
#include "ofxGui.h"
class ofApp : public ofBaseApp{
public:
void setup();
void draw();
vector<unique_ptr<ofxPanel>> uniquePanels;
ofParameter<float> f0 = {"f0", 0, 0, 1};
ofParameter<float> f1 = {"f1", 0.3, 0, 1};
ofParameter<float> f2 = {"f2", 0.6, 0, 1};
ofParameter<float> f3 = {"f3", 1, 0, 1};
};
#include "ofApp.h"
//--------------------------------------------------------------
void ofApp::setup(){
ofRectangle prevShape(20,20,0,0); // just to keep track of the shape of the previous gui, so we can layout all these nicely
for(int i = 0; i < 4; i++){
uniquePanels.push_back (make_unique<ofxPanel>());
uniquePanels[i]->setup("panel" + ofToString(i), "", prevShape.x, prevShape.getMaxY());
uniquePanels[i]->add(f0);
uniquePanels[i]->add(f1);
uniquePanels[i]->add(f2);
uniquePanels[i]->add(f3);
prevShape = uniquePanels[i]->getShape();
}
}
//--------------------------------------------------------------
void ofApp::draw(){
for(int i = 0; i < uniquePanels.size(); i++){
uniquePanels[i]->draw();
}
}