如何(重新)调用初始化对象的构造函数
How to (re)call a constructor of an initialised object?
我正在编写一些代码,检查是否插入了特定的midi设备,如果没有,代码每5秒重新检查一次,直到它插入。
我的问题是在检查设备列表时出现的——外部库没有重新检查端口的函数,因为它只在类的构造函数中检查端口。
我能看到的让我的代码重新检查设备列表的唯一方法是重新初始化类对象。
类对象在头文件中声明为ofxMidiIn midiIn;
,因为它在cpp文件中全局使用。问题是,如果我在cpp中的函数内"重新声明",它似乎不会取代全局作用域中的对象,即使它在局部很好。
用伪代码来澄清:
在。h:
class foo {
ofxMidiIn midiIn; //first initialization does a port scan
};
.cpp:
void foo::setup(){
midiIn.listPorts(); //if this fails the recheck is triggered every 5 secs
}
void foo::run(){
//if setup failed then while (!recheck());
}
bool foo::recheck(){
ofxMidiIn midiIn;
midiIn.listPorts(); //this works in this (local) scope, but doesn't reassign midiIn globally
}
通过使用placement new
,您可以重新调用构造函数:
bool foo::recheck()
{
new (&midiIn) ofxMidiIn();
midiIn.listPorts();
}
行new (&midiIn) ofxMidiIn()
将通过调用ofxMidiIn
的构造函数在自己的内存区域中重构midiIn
。但是,如果ofxMidiIn
有指针,并且您已经在前面的对象中为它们分配了内存,那么这种方法将会产生问题。你将会泄漏内存。你可以显式地调用析构函数,这样写:
(&midiIn)->~ofxMidiIn(); //call the destructor explicitly
new (&midiIn) ofxMidiIn(); //then do this!
Demo: http://ideone.com/OaUtw
无论如何,我相信更好和干净的解决方案是使变量为指针为:
ofxMidiIn *midiIn;
然后使用new
和delete
。当您下次执行new
时,必须通过如下方式删除前一个对象:
bool foo::recheck()
{
delete midiIn; //must do this if it already has been allocated memory!
midiIn = new ofxMidiIn();
midiIn->listPorts();
}
不应该两次调用构造函数。它可能经常导致未定义的行为和不可维护的代码。
而是将构造函数代码的内容复制到类成员函数中(可能是private
),然后在需要时调用该函数。例如
class foo {
void check ()
{
// put constructor logic here
}
public:
foo ()
{
//...
check();
}
// now call 'check()` wherever you want
};
使用指针代替实例成员
class foo {
ofxMidiIn* midiIn;
};
foo::foo()
{
midiIn = new ofxMidiIn;
}
foo::~foo()
{
delete midiIn;
}
void foo::setup(){
midiIn->listPorts(); //if this fails the recheck is triggered every 5 secs
}
void foo::run(){
//if setup failed then while (!recheck());
}
bool foo::recheck(){
delete midiIn;
miniIn = new ofxMIdiIn;
midiIn->listPorts(); //this works in this (local) scope, but doesn't reassign midiIn globally
}
在不了解这个特定类的情况下,立即的解决方案似乎是赋值。
ofxMidi midiIn;
void function() {
ofxMidi localMidi;
if(we_have_our_new_data)
midiIn = localMidi;
}
如果ofxMidi
不可赋值,以某种方式包装对象是合适的。
std::shared_ptr<ofxMidi> midiIn;
void function() {
std::shared_ptr<ofxMidi> localMidi(new ofxMidi);
if(we_have_our_data)
midiIn = localMidi;
}
在需要重新创建时使用指向ofxmidin的指针和动态分配。请确保遵循三个规则或继承boost::noncopyable
没有看到更新的midin的原因是您实际上创建了两个实例—一个本地实例和一个成员变量。recheck()中的本地副本遮蔽了成员变量。在这一点上,我建议您调高编译器的警告级别,这样您就不会在其他地方意外地被此问题烫伤。
我个人会将midin封装在std::shared_ptr中并重新初始化它。像这样:#include <memory>
class foo {
std::shared_ptr<ofxMidiIn> midiIn; //first initialisation does a port scan
foo() : midiIn(std::make_shared<ofxMidiIn>() ){} //Constructor
bool recheck(){
midiIn = std::make_shared<ofxMidiIn>(); //Will blow away the old midiIn and replace it with a new one.
midiIn->listPorts();
}
};
- 类中的 Arduino 对象构造函数设置垃圾值
- 编译错误:临时对象构造函数中缺少参数
- 双指针在使用 new 时不调用对象构造函数
- 以支持继承的方式将自身shared_ptr添加到对象构造函数中的向量中
- 在创建对象向量时,不为每个对象唯一调用默认对象构造函数
- GCC __attribute__((constructor)) 在对象构造函数之前调用
- 自定义对象构造函数在循环外部循环
- 从全局对象构造函数停止监视器计时器
- Arduino 上的 Sketch 停止在对象构造函数中执行
- 通过在引用线程对象来传递取消引用的“this”指针来在函数对象构造函数中创建线程是好是坏
- 为什么当对象构造函数投入新表达式时,为什么不调用DealLocation函数
- 临时结构对象构造函数奇数调用
- 未显式引用对象的全局对象构造函数在最终二进制文件 - LD 中被丢弃
- 为什么 Clang++ 不在另一个静态库中运行全局对象构造函数?
- 在未加载上下文的情况下在对象构造函数中使用OpenGL函数
- 为什么我们需要一个用户提供的const对象构造函数
- 对象构造函数的C++数组
- 将子结构值设置为对象构造函数中安全的纯虚拟函数返回的值
- C等价于新对象(构造函数)
- C++:直接在参数列表中使用数组文字的对象构造函数