我在实例化一个生活在一个类中的结构时遇到了一个奇怪的问题,在构造中它调用了析构函数(多次),甚至调用了父对象的析构函数。
具有结构的类:
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(...);
}
调用的结果集,“对象”是StepModelIO
,“父”是Model
:
- 使用复制构造函数构造父级
- 构造对象
- 破坏父级
- 使用复制构造函数构造对象
- 使用复制构造函数构造父级
- 构造对象
- 破坏父级
- 破坏对象
- 破坏对象(再次...)
- 破坏父级
不出所料,StepModelIO
在这一切发生之后,生成的结构 (a ) 状态并不好,而且路径似乎很荒谬。我有这样的结构,以便在父模型对象上使用相同的泛型,这可以解释一些问题。
我曾尝试(也许是天真地)在构造函数和析构函数上使用“三规则”,我可能把它搞砸了。
编辑:完整代码
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]);