析构函数的异常调用
Unusual calling of destructor
我在实例化类中的结构时遇到了一个奇怪的问题,在构造中它调用析构函数(多次),甚至调用父对象析构函数。
带结构的类:
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
)的状态并不好,路径看起来很荒谬。我像这样放置结构,以便在父模型对象上使用相同的泛型,这可能会解释一些问题。
尝试(也许天真地)在构造函数和析构函数上使用"三法则",有可能我把它搞得很糟糕。
编辑:完整代码
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]);
您正在按值传递事物,这将导致临时对象被构造和破坏。改为通过常量引用传递它们。
改变
StepModelIO(Model model, ...)
自
StepModelIO(const Model &model, ...)
您现在已更改代码。所以你真的想要这个,我想。
StepModelIO(const Model<U, V> &model, const U &u, const V &v)
我注意到类内部有 tat StepModelIO
你有一个成员Model<U, V> model;
所以对于类的每个实例StepModelIO
模型的析构函数也将被计算; 第一~StepModelIO()
和第二~Model<U, V>()
所以给定你提供的代码:
Model::StepModelIO stepArgs = Model::StepModelIO(...);
这有两个类型为 StepModelIO
的对象。一个是右侧的 on(右值),第二个是 stepArgs
.
首先调用右侧析构函数,结果为:
1: Destruct StepModelIO
2:Destruct Model
当 stepArgs 的破坏发生时:
3: Destruct StepModelIO
4:Destruct Model
相关文章:
- C++/CLI System.AccessViolation在托管类中调用非托管函数时出现异常
- 尝试在 QT 项目中调用 Java 代码时未找到类异常
- 调用参数不是原子参数的函数是此代码引发异常的原因吗?
- 从 C# 调用 C++ DLib 会导致错误的分配异常
- 在 postOrderDelete 上调用析构函数时引发的异常
- memcpy() 在一个类中被调用以复制到另一个类变量中后会引发异常
- 为什么在析构函数中引发异常时不调用重载删除
- CPP 异常获取抛出调用方的详细信息
- 为什么要抛出引用调用复制构造函数的异常?
- 析构函数中的互斥锁C++在 Python 中调用 exit() 时会导致异常
- 调试"在抛出 ..) 实例后终止调用",当异常 _should_ 被捕获时
- 调用系统调用函数时出现异常
- 如果从在其他函数中调用的函数引发异常会发生什么情况
- C++函数中引发异常并在调用方中捕获它
- 防止线程在处理异常后在分离时调用 std::terminate()
- 如果从类成员初始值设定项引发的异常调用 std::terminate()
- JNI GetMethodID 调用,带有挂起的异常 java.lang.ClassNotFoundException
- throw() 函数应该总是在异常时展开堆栈并允许捕获异常还是必须调用 std::terminate ?
- 从catch块调用异常类中的函数并不是打印从try块传递的值
- 为什么在构造函数调用异常后不释放unique_ptr