From: RB on

> It has nothing to do with throw.
> ClassNoObject() creates a temporary of this class, just as int() creates
> a temporary int.
> You can also do, for example:
> // returns a copy of this temporary
> return ClassNoObject();
> // creates a temporary string containing "foo" and returns a copy of it
> return std::string("foo");
> The same works for throw.
> Thomas

Wow I did not know that. But knowing that, is there a way to
pass a reference to the this temp object ( if it was fairly large )
so I would not have to pass it on the stack by value ?
From: RB on

> But knowing that, is there a way to pass a reference to the this
> temp object ( if it was fairly large ) so I would not have to pass
> it on the stack by value ?

Ugh after thinking about my statement I sense my folly since the
temp object is probably already on the stack.

From: Goran on
On Jun 24, 11:45 pm, Giovanni Dicanio
<giovanniDOTdica...(a)REMOVEMEgmail.com> wrote:
> On 24/06/2010 18:22, Bo Persson wrote:
>
> >> catch( ClassNoObject E )
> >>   {
> >>    E.ClsNoObjFunc();
> >>    cout<<  "Caught exception\n";
> >>   }
> >> }
>
> > Right, you catch the exception object by value. Quite ok.
>
> But I used to think that the correct way to catch exceptions is by
> (const) reference:
>
>    catch (SomeException & e)
>
> or
>
>    catch (const SomeException & e)

That's correct. In "normal" C++, one should do catch(const
exception_type&). Occasions where catch by value is good are seriously
rare (e.g. when one is using really small exception object; I have one
place (very low level code, no MFC) where I throw an object containing
only GetLastError. There, It's silly to catch by ref).

catch by value runs the danger of having another exceptions being
thrown at the catch site, from copy constructor of exception object,
and const is normal because, why would one ever change any exception
object? That equals to cheating, e.g. changing the potential error
info.

(MFC exceptions are, sadly, another story. e.g. ReportError and
GetErrorMessage should have been const. And as said in the past days,
they should not have been thrown through pointers).

Goran.
From: Goran on
On Jun 24, 5:12 pm, "RB" <NoMail(a)NoSpam> wrote:
> I have a question on try throw semantics. This has
> nothing to do with whether I should try or catch but
> just the fact that I don't understand what is going
> on here. Admittedly this is not any real code but a
> scenario that I happened on by accident in experimenting
> with writing my own exception class. The below code
> compiles and runs with no errors but a newb like me
> doesn't understand how. See comment on GlobalFunc
>
> #include <iostream.h>
>
> class ClassNoObject
> {
>  public:
>  ClassNoObject(){}
>  ~ClassNoObject(){}
>  void ClsNoObjFunc()  
>   {
>    cout << "no object class printing? \n";
>   }
>
> };
>
> void GlobalFunc()
> {  // How can throw construct a class definition with
>    // no object, but seemingly does in the debugger ?
>   // What is happening here ?
>
>   cout << "fixing to throw ClassDefinition? \n";
>   throw ClassNoObject();
>
> }
>
> void main(void)
> {
>  try
>   {
>    GlobalFunc();
>   }
>
> // The E instead of * E appears it is passing a copy,
> // but a copy of what object ?
>
>  catch( ClassNoObject E )    
>   {
>    E.ClsNoObjFunc();
>    cout << "Caught exception\n";
>   }
>
> }

Other people already explained a lot. I'll just add that in context of
MFC you should always use exception object derived from some MFC
exception class, you should throw them like so: throw new
CMyExceptionClass(params), and you should catch them like so:
catch(CMyException* pe). This is, sadly, different from "standard C++"
way of doing things. (see my other post).

Goran.
From: Jeff Flinn on
RB wrote:
>
>> It has nothing to do with throw.
>> ClassNoObject() creates a temporary of this class, just as int() creates
>> a temporary int.
>> You can also do, for example:
>> // returns a copy of this temporary
>> return ClassNoObject();
>> // creates a temporary string containing "foo" and returns a copy of it
>> return std::string("foo");
>> The same works for throw.
>> Thomas
>
> Wow I did not know that. But knowing that, is there a way to pass a
> reference to the this temp object ( if it was fairly large ) so I would
> not have to pass it on the stack by value ?

The generally accepted approach is to throw by value, which you've done,
and catch by [const] ref. This is contrary to most of Microsoft's
code, which new's up an exception on the heap and throws the pointer.

catch( ClassNoObject& E )
{
E.ClsNoObjFunc();
cout << "Caught exception\n";
}
}

Why would your object ever need to be "fairly large"? You might want to
get a book and/or google C++ exceptions. To do right, an exception
architecture takes thought and effort.

Jeff