WaldB
WaldB

Reputation: 1261

How to catch an exception from a private member subclass object?

Given the pseudo-code below, I want to catch the exception thrown by the sub-object a in class B, maintaining this object private in B. The catch clause as stated below doesn't work because the object a is private in B. How can I catch this exception ?

Edit I have changed the pseudo-code to embed class A within class B.

class B
{
    class A
    {
        public:
        class Exception{};
        A() throw(Exception) { ... }  // A ctor throws an Exception class object
    } a;
    public:
    B() { ... }     //  B ctor
};

int main()
{
    try
    {
        B b;
    }
    catch( B::A::Exception& )
    {
        ...
    }

}

Upvotes: 1

Views: 498

Answers (4)

cHao
cHao

Reputation: 86555

You don't need to say B::A::Exception in the catch clause, unless the class A is defined inside B. Now that you've edited it to make it so, B::A::Exception is appropriate if A is visible outside of B and Exception is visible outside of A...or if B::A::Exception is made available some other way (like via a typedef, as suggested by pmr).

And if it isn't, you shouldn't be throwing it at all. (It's not, in this case, so yeah. Don't do that.) How is anyone going to reasonably catch that exception if they can't even see the type of it?

A way you could make this work is to split the declaration of the class from the declaration of the member variable. Kinda like

class B {
 public:
    B() { }

    class A {
     public:
        class Exception {};
        A() { /* throw Exception(); */ }
    };
 private:
    A a;
};

But frankly, the typedef sounds way more elegant.

Upvotes: 3

Carl
Carl

Reputation: 44488

You might want to rethink throwing exceptions in a constructor. Here's why (the destructor will not get called when you throw an exception)

Exceptions are really for exceptional circumstances. Don't overuse them.

Upvotes: 1

pmr
pmr

Reputation: 59841

Add a typedef to the exception in the surrounding class.

class B
{
    class A
    {
        public:
        class Exception{};
        A() throw(Exception) {  }  // A ctor throws an Exception class object
    } a;

public:
  typedef A::Exception Except;
    B() {  }     //  B ctor
};

int main()
{
    try
    {
        B b;
    }
    catch( B::Except& )
    {

    }

}

Upvotes: 1

André Puel
André Puel

Reputation: 9189

Since A is private, you can't access the type Exception to catch it. There are a few solutions, first is catch anything:

try {
    B b;
} catch(...) {
}

Second is to create a separated Exception class that is visible in main.

And finally, you could make your B::A::Exception extend std::Exception and catch std::Exception.

Upvotes: 0

Related Questions