Eli*_*ard 1 c++ design-patterns overloading shared-ptr c++11
我正在制作一个粒子系统,我正在努力构建我的代码.这个想法是用户可以创建一个或多个ParticleEmitter通过ParticleManager对象传递给对象的ofxCurlNoise对象.
现在,我希望当用户更新ParticleEmitters对象时,ParticleManager对象会看到所做的更改.所以我使用了共享指针,但是我在不同的时间都有分段错误,无论是使用一个ParticleEmitter(程序启动时的分段错误)还是vector<ParticleEmitter>(程序退出时的分段错误).
这有什么问题?做我正在做的事情的设计模式是什么?
ofApp.h
#include "ofxCurlNoise.h"
class ofApp : public ofBaseApp{
// ParticleEmitter particleEmitter;
vector<ParticleEmitter> particleEmitters;
ofxCurlNoise curlNoise;
public:
void setup();
};
Run Code Online (Sandbox Code Playgroud)
ofApp.cpp
#include "ofApp.h"
void ofApp::setup(){
// This produces a segfault as soon as the program starts
// particleEmitter.setup();
// curlNoise.setup(particleEmitter, 1024*256);
// This produces a segfault when the program exits
ParticleEmitter emitter;
emitter.setup();
particleEmitters.push_back(emitter);
curlNoise.setup(particleEmitters, 1024*256);
}
Run Code Online (Sandbox Code Playgroud)
ofxCurlNoise.h
#include "ParticleManager.h"
class ofxCurlNoise {
ParticleManager particleManager;
public:
void setup(ParticleEmitter& emitter, int n);
void setup(vector<ParticleEmitter>& emitters, int n);
private:
void setup(int n);
};
Run Code Online (Sandbox Code Playgroud)
ofxCurlNoise.cpp
#include "ofxCurlNoise.h"
void ofxCurlNoise::setup(ParticleEmitter& emitter, int n){
particleManager.addEmitter(shared_ptr<ParticleEmitter>(&emitter));
setup(n);
}
void ofxCurlNoise::setup(vector<ParticleEmitter>& emitters, int n){
for(auto& e : emitters){
particleManager.addEmitter(shared_ptr<ParticleEmitter>(&e));
}
setup(n);
}
void ofxCurlNoise::setup(int n){
particleManager.setup(n);
}
Run Code Online (Sandbox Code Playgroud)
ParticleManager.h
#include "ParticleEmitter.h"
class ParticleManager{
vector<shared_ptr<ParticleEmitter>> emitters;
public:
void addEmitter(const shared_ptr<ParticleEmitter>& emitter);
void setup(int n);
};
Run Code Online (Sandbox Code Playgroud)
ParticleManager.cpp
#include "ParticleManager.h"
void ParticleManager::setup(int n){
//...
}
void ParticleManager::addEmitter(const shared_ptr<ParticleEmitter>& emitter){
emitters.push_back(emitter);
}
Run Code Online (Sandbox Code Playgroud)
这不是多么std::shared_ptr有效.您正在ParticleEmitter堆栈上创建实例,但std::shared_ptr用于管理在堆上创建的实例.在你的代码中,当你向它添加一个新的发射器ParticleManager并将其包装到一个共享指针中时,当particleEmitters向量被销毁时(反过来,你的ofApp实例被销毁)会破坏发射器并因此被破坏.
当的实例ofApp被破坏,两者的实例ofxCurlNoise和particleEmitters被破坏(按该顺序).所以ofxCurlNoise将反过来破坏particleManager管理你的共享指针,然后删除你的粒子发射器(最初是在堆栈上创建的).完成所有操作后,particleEmitters矢量将被破坏,运行时系统将再次尝试销毁粒子发射器,从而导致您看到的错误.
此外,共享指针用于建模共享所有权语义,我在您的用例中没有看到.我认为你最好还是std::unique_ptr用来管理在堆上创建的实例,或者根本不使用智能指针并在堆栈上创建所有东西(你几乎已经在做了).