Reputation: 4276
I have the below code snippet which is to demonstrate use-case of function-try-block for constructor. Because the constructor of Controller
throws no object of it gets created successfully, i.e. the client_
member variable should no longer exist too when exception is thrown, is that correct? If so then is that safe to call deinit()
which is to clean-up the client_
? If not safe, say if client_
was a raw pointer which then how would I catch the exception and do clean-up stuff for it?
class Client {
public:
Client() { std::cout << "Client()" << std::endl; }
~Client() { std::cout << "~Client()" << std::endl; }
void Start() { throw "Start() failed with exception"; }
};
class Controller {
private:
std::shared_ptr<Client> client_;
public:
Controller() try {
client_ = std::make_shared<Client>();
client_->Start();
} catch (...) {
deinit();
}
~Controller() {
deinit();
}
private:
void deinit() {
if (client_) {
client_.reset();
}
}
};
Upvotes: 0
Views: 81
Reputation: 118415
the client_ member variable should no longer exist too when exception is thrown, is that correct?
No this is incorrect. The exception gets thrown after the client_
member of the new class instance gets constructed.
A class's constructor gets called only after all members of the new class instance get constructed; and the constructor's job is to do whatever it means to construct the class itself, after all the class members get constructed.
Once you're in the constructor, you're guaranteed that all the members of the new class instance are fully constructed. You can take that to the bank.
is that safe to call deinit()
Well, it's "safe" since it's defined behavior. But, in this case, it is completely unnecessary. If an exception gets thrown in the constructor, all constructed members of the new class instance get automatically destroyed, in reverse construction order. client_
will get destroyed normally, as if it would if the class fully constructed and then destroyed at some point later.
if client_ was a raw pointer which then how would I catch the exception and do clean-up stuff for it?
Pretty much the way the shown code does it. But it is not a raw pointer, but a shared_ptr
, which handles this.
Upvotes: 1