Reputation: 7424
Lets consider having a class with a constructor throwing an exception like following:
class Class
{
public:
Class(type argument)
{
if (argument == NULL)
{
throw std::exception("Value cannot be null.\nParameter name: argument");
}
// Instructions
}
private:
// Properties
}
Since the class constructor might throw an exception we cannot declare an object directly.
Class obj(argument); // Harmful
Which means the constructor must be called must be using a try/catch
try
{
Class obj(argument);
}
catch (std::exception& ex)
{
std::cout << ex.what() << std::endl;
}
The problem is that we can only use the object inside the try block. The only way to use it outside of the try block is to declare a Class* pointer then use the new keyword to construct a new object then assign it's address to the previous pointer.
Class* pObj;
try
{
pObj = new Class(argument);
}
catch (std::exception& ex)
{
std::cout << ex.what() << std::endl;
}
So what is the standard way to define the previous class in order to create instances without using pointers or dynamic memory allocation?
Thank you in advance
Upvotes: 6
Views: 2979
Reputation: 103693
Since the class constructor might throw an exception we cannot declare an object directly.
Yes, you can. You only need to put it in a try block if you actually have a plan to deal with an exception right there, in the function. If you don't have such a plan, then just let the exception propogate (though you should catch it eventually, just to provide a report if nothing else).
But, assuming you do have a plan to handle the exception right there in the function, then the solution is simple.
try {
Class obj(argument);
// use obj here, inside the try block
}
catch(...) { ... }
// not here, outside the try block
Edit: By your comment below, either you are misunderstanding me, or I am misunderstanding you. Perhaps a concrete exaqmple is required. Let's say that this is your function which uses your class:
void Foobar(type argument)
{
Class obj(argument);
obj.method1(1,2,3);
obj.method2(3,4);
int x = Wizbang(obj);
gobble(x);
}
Now, you want to handle the exception that the Class
constructor might throw. What I'm suggesting is putting all of that junk in the function, into a try block, thusly:
void Foobar(type argument)
{
try
{
Class obj(argument);
obj.method1(1,2,3);
obj.method2(3,4);
int x = Wizbang(obj);
gobble(x);
}
catch(std::exception& e)
{
std::cout << e.what() << std::endl;
}
}
If you can't do this, please explain why. You've said "I need access to use the object later", but you've provided no reason why "later" cannot mean "later within the same try block where the object was created". As such, your requirements are incomplete.
Upvotes: 4
Reputation: 2130
What you want is not (reasonably) possible. Suppose there were some method of doing what you want, that is, creating an object obj of type Class that was still in scope outside any relevant try{}catch{} construct used to handle exceptions in the constructor. Thw question to ask yourself is, if an exception were to be thrown during construction of the obj, and you somehow handled the exception and then execution were to continue in the block where the obj was still in scope, what exactly would the obj contain? It was never constructed, so just what would be in the obj????
Upvotes: 0