I have a Player
object which can throw an exception inside its constructor, so in my main function I'm creating 2 Player
objects inside a try block.
I want to store these 2 Player
s in a std::array
like that:
try
{
Player p1(10, 10, ikazuchi);
Player p2(70, 10, hibiki);
std::array<Player, 2> players = {p1, p2};
}
The problem is that I wouldn't be able to use the array outside of the try block, and I heard that placing all the main
code inside a try block is often a bad idea.
I can't declare my std::array
after the try block because p1
and p2
no longer exist there.
I can solve the problem with a std::vector
, but I have read that it was better to use a std::array
when I know the size of the array during the compilation.
I could create a default constructor to create my objects then fill them inside the try block, but it seems to be more proper to create everything in the constructor.
What would be the best practice for that?
You can always get around issues like this using dynamic allocation or something like boost::optional<std::array<Player, 2>>
, but the real question is: should you? That is, assume one of the player objects fails to construct and throws an exception. What will you do with the players
array after that? It's not in a legal state, or at least not in the state you'd expect it to be if no exception was thrown.
There is no problem with having the scope of a try
be large. It should cover everything where an exception will prevent you from progressing. If you don't like physically having a lot of source code there, move the code into a function. This might be a good idea anyway: one function which assumes all goes well, and another one whose chief responsibility is to handle errors.
And if you have meaningful ways of continuing to use players
when the objects inside are in an invalid state (constructor threw), then you can just create the array with objects in that state in the first place (outside the try
block), and just assign them inside the try
.
The question states you don't want to provide an unneeded default constructor, but I claim that either player
belongs inside the try
, or Player
needs a default constructor (or an equivalent way of expressing "not initialised properly).