Reputation: 4477
I'm new to C++ and was wondering if you could do the following, or if you have a better way.
I have a custom exception class for my database handler: I use this in my main like this:
int main(int argc, char const ** argv){
try {
DatabaseHandler DGeneDB = DatabaseHandler("string/to/path");
}catch(DatabaseHandlerExceptions &msg) {
std::cerr << "Couldn't open Database" << std::endl;
std::cerr << msg.what();
return 1;
}
DGeneDB.foo() //Can't access this object since it was initialized in try statement
return 0;
}
I have a billion things I want to do with the DGeneDB object and don't want to do it all within the try statement. I only want to catch the constructor exception that is thrown during initialization. What should I do to work with the object outside of try? I mean, if it throws the exception, it will return 1 and will stop main() before it gets to the other object.
Upvotes: 8
Views: 1944
Reputation: 71
If you have access to C++17 (and your type has a move constructor), you could use std::optional for that:
std::optional<DatabaseHandler> database{};
try {
database = DatabaseHandler{arguments};
}
catch (const YourExceptionTypeHere &exception) {
// ...
return 1;
}
database->foo();
This way you'll still be able to initialize the object in the try block as you wish, without having to modify your constructor or resorting to heap memory allocations (new/unique_ptr).
If the pointer like syntax/nature of std::optional bothers you, you could also move the object out of the std::optional after you initialize it:
DatabaseHandler real_database{std::move(*database)};
real_database.foo();
Upvotes: 0
Reputation: 1
You can use a pointer:
DatabaseHandler *DGeneDB;
try {
DGeneDB = new DatabaseHandler("string/to/path");
}catch(DatabaseHandlerExceptions &msg) {
// your error stuff here
}
DGeneDB->foo();
But don't forget to delete it after use.
Upvotes: 0
Reputation: 31597
Does your Databasehandler
have an open
method, or something similar? If not, create one and modify that constructor so that it doesn't open the database connection anymore (so it won't throw). Your code would look like this:
DatabaseHandler DGenDB;
try {
DGenDB.open(dbpaths.Dgene_db);
}
catch (DatabaseHandlerExceptions &msg) {
return 1;
}
Note: In your original code you have a line like this:
DatabaseHandler DGeneDB = DatabaseHandler(dbpaths.Dgene_db);
That is an unusual way to initialize variables in C++. You could have just written:
DatabaseHandler DGeneDB(dbpaths.Dgene_db);
Upvotes: 4