Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ class constructor throwing an exception

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

like image 344
rullof Avatar asked Sep 10 '14 02:09

rullof


People also ask

What happens if a constructor throws an exception?

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.

Is it OK to throw exception in constructor C#?

Throwing exceptions in constructors in C# is fine, but a constructor should always create a valid object.

Can we handle exception in constructor?

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.

Can a copy constructor throw an exception?

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.


1 Answers

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.

like image 139
Benjamin Lindley Avatar answered Sep 27 '22 02:09

Benjamin Lindley