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
When throwing an exception in a constructor, the memory for the object itself has already been allocated by the time the constructor is called. So, the compiler will automatically deallocate the memory occupied by the object after the exception is thrown.
Throwing exceptions in constructors in C# is fine, but a constructor should always create a valid object.
Yes, constructors are allowed to throw an exception in Java. A Constructor is a special type of a method that is used to initialize the object and it is used to create an object of a class using the new keyword, where an object is also known as an Instance of a class.
However, the copy constructor for an exception object still must not throw an exception because compilers are not required to elide the copy constructor call in all situations, and common implementations of std::exception_ptr will call a copy constructor even if it can be elided from a throw expression.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With