failed constructor and failed destructor in C++

試著忘記壹切 提交于 2019-12-07 09:22:55

问题


I have one question about failed constructor and failed destructor in C++.

I noticed that when the constructor failed, an exception will be thrown. But there is no exception thrown in destructor.

My question is

1) If constructor failed, what exception will be thrown? bad_alloc? or anything else related? Under what situation, a constructor would fail? What about the successfully constructed part?

2) Under what situation, a destructor would fail? If no exception is thrown, what would happen to the destructor? How does the compiler deal with it? What's the return value to the function it is called?

Thanks!

Any comments are strongly appreciated!


回答1:


  1. If a constructor fails, an exception is thrown only if the constructor is implemented so that it throws an exception. (You might need to differentiate between memory allocation and construction. Allocating memory using new might fail throwing a std::bad_alloc exception.)

  2. There is no case where a constructor, in general, fails. It fails only if it is written so that it might fail. If so, how it fails depends on how it is written. In general, destructors should be written so they don't fail, as it is not safe to throw exceptions from destructors. (That's because they might be called during stack unwinding.)

Note that "failing" as used in your question generally refers to runtime failures. So the compiler has nothing to do with it. Also, neither constructors nor destructors return anything.




回答2:


The exception that is thrown when a constructor fails is determined by the constructor itself, either because it throws directly, or by the actions it takes (like calling another function that might throw an exception).

Constructors can fail when they try to acquire a resource that is not available, like memory, a file handle, a screen window, etc. If new fails, it'll throw std::bad_alloc. If the constructor doesn't catch it, then that will propagate out of the constructor.

C++ has no good way to deal with errors in a destructor. To the extent possible, you should design destructors to not fail. You should never throw an exception from a destructor. And if a function you call in a destructor might throw an exception, you should either catch it (if you know it's safe to ignore) or crash immediately.




回答3:


If your destructor throws an exception you're doing something wrong. Throwing an exception in the destructor can lead to several problem areas: items used from socket/thread/object pools may become permanently trapped in an unretreivable state, memory may not be deallocated, or logic which for some reason you placed in the destructor may not get called.

All the same reasons that an exception might get thrown in code elsewhere can cause an exception to be thrown in a destructor. Most notably if you've got a dangling pointer somewhere attempting to clean up currently used memory can cause a system exception. Good luck handling that.




回答4:


Constructor in this context is "just" a user function, it can throw any exceptions it wants. If a constructor doesn't throw an exception, it's considered not be failed.

So: a constructor doesn't fail on its own. If it throws an exception itself, it failed. If it doesn't, no special code is implicitly added by compiler to throw any exceptions.

The same is true for destructors, too.




回答5:


If a constructor fails, well, it throws some exception. It doesn't have to be because memory couldn't be allocated; anything else that would throw an exception will make it fail, and that includes throw statements you write yourself. The idea is generally either to create a usable object or throw an exception.

If a constructor fails, there is no successfully constructed part. It's all gone.

I don't know what is meant by a destructor failing. It will execute any applicable code, and doesn't return anything. If the code is badly written, it can fail to do what the programmer wants, but that's true of all functions.

Destructors should never throw exceptions. (They can call routines that throw, but they should catch all exceptions and deal with them themselves.) If a destructor throws, and it's called because an exception has been thrown and it's unwinding the stack, the program crashes, one way or another. (There are mechanisms to try to tell if the stack is unwinding or not, but at best you're writing a destructor two different ways, and it's hard to test both of them.)




回答6:


In addition to everything mentioned here, operator new can throw bad_alloc before it calls the constructor. The constructor only starts running after a piece of memory exists for the object instance to exist in (although it doesn't fully exist until the constructor finishes).



来源:https://stackoverflow.com/questions/2343191/failed-constructor-and-failed-destructor-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!