我遇到一个奇怪的问题,实例化一个生活在类中的结构,在构造中它调用析构函数(多次),甚至调用父对象析构函数。
具有结构的类:
class Model {
public:
struct StepModelIO {
StepModelIO(Model model, ...) {DoConstruction(Model model, ...);}
StepModelIO(const StepModelIO &other) {DoConstruction(Model model, ...); }
~StepModelIO() {}
DoConstruction() {
...
}
}
Model(...) {
...
}
Model(const Model &other) {DoConstruction(...);}
~Model() {
...
}
private:
DoConstruction(...) {
}
}
通话功能:
void main() {
Model::StepModelIO stepArgs = Model::StepModelIO(...);
}
生成的一组调用,其中'object'为StepModelIO
,'parent'为Model
:
不出所料,在这一切发生之后,所得到的结构(StepModelIO
)并未处于良好状态,并且这条路似乎很荒谬。我有这样的结构在父模型对象中使用相同的泛型,这可以解释一些问题。
我曾尝试(或许是天真的)在构造函数和析构函数中使用“三规则”,但我可能会严重阻止它。
修改:完整代码
template<typename U, typename V>
class Model{
public:
struct StepModelIO {
Model<U, V> model;
U u;
V v;
StepModelIO() {}
StepModelIO(Model<U, V> model, U u, V v) {
this->model = model;
this->u = u;
this->v = v;
}
StepModelIO (const StepModelIO &other) {
StepModelIO(other.model, other.u, other.v);
}
~StepModelIO() {
}
};
Model(char * libraryPath) {DoConstruction(libraryPath);}
Model() {}
Model (const Model &other) {
DoConstruction(other.m_LibraryPath);
}
~Model() {
this->Stop();
}
void Init() {
if (!this->m_Initialised) {
this->ModelInit();
m_Initialised = true;
}
}
void Stop() {
if (this->m_Initialised) {
this->ModelStop();
m_Initialised = false;
}
}
void Restart() {
this->ModelRestart();
}
void Step(U u, V v) {
ModelStep(u, v);
}
private:
char* m_LibraryPath;
HINSTANCE m_ModelDLL;
bool m_Initialised;
typedef int (__cdecl * EmptyModelFunctionPointer)(); // Interpret integer as C code pointer named 'EmptyModelFunctionPointer'
typedef int (__cdecl * ModelFunctionPointer)(U u, V v);
EmptyModelFunctionPointer ModelInit;
EmptyModelFunctionPointer ModelStop;
EmptyModelFunctionPointer ModelRestart;
ModelFunctionPointer ModelStep;
virtual void DoConstruction(char * libraryPath){
this->m_Initialised = false;
this->m_LibraryPath = libraryPath;
this->m_ModelDLL = LoadLibrary(libraryPath);
this->ModelInit = GetFunction<EmptyModelFunctionPointer>(m_ModelDLL, "Init");
this->ModelStop = GetFunction<EmptyModelFunctionPointer>(m_ModelDLL, "Stop");
this->ModelRestart = GetFunction<EmptyModelFunctionPointer>(m_ModelDLL, "Restart");
this->ModelStep = GetFunction<ModelFunctionPointer>(m_ModelDLL, "Step");
}
template<typename pointerType>
pointerType GetFunction(HINSTANCE modelLibrary, char * functionName){
return (pointerType)GetProcAddress(HMODULE (modelLibrary),functionName);
}
};
呼叫者:
StepModelIO<Type_1*, Type_2*> stepArgs = StepModelIO<Type_1*, Type_2*>(newModel, &a, &b[0]);
答案 0 :(得分:2)
您按值传递事物,这将导致构造和销毁临时对象。改为通过const引用传递它们。
变化
StepModelIO(Model model, ...)
到
StepModelIO(const Model &model, ...)
您现在已经更改了代码。我想你真的想要这个。
StepModelIO(const Model<U, V> &model, const U &u, const V &v)
答案 1 :(得分:1)
我在类StepModelIO
中注意到你有一个成员Model<U, V> model;
所以对于每个类StepModelIO
的实例,模型的析构函数也会被篡改;第一个~StepModelIO()
和第二个~Model<U, V>()
所以给出你提供的代码:
Model::StepModelIO stepArgs = Model::StepModelIO(...);
这有两个StepModelIO
类型的对象。一个是右边的开(右边),第二个是stepArgs
。
首先调用右边那个的析构函数,得到:
1:Destruct StepModelIO
2:Destruct Model
当stepArgs发生破坏时:
3:Destruct StepModelIO
4:Destruct Model