rullof
rullof

Reputation: 7424

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

Upvotes: 6

Views: 2979

Answers (2)

Benjamin Lindley
Benjamin Lindley

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

David I. McIntosh
David I. McIntosh

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

Related Questions