简体   繁体   中英

Avoiding copies in exception handling

Can I avoid the copying of object in the following way?

MyClass Obj;

try {
    throw &Obj;
}
catch(MyClass *a) {

}

If the object is too expensive to copy, it should not be thrown as an exception - full stop. Exception classes should be fairly simple and light-weight. And you should always catch exceptions by reference (probably by const reference) - catching pointers is bad style. So your code should better be written:

try {
    throw MyClass();
}
catch( const MyClass & a) {
}

In response to your comment, this:

struct A {
    A() {}
    private:
    A( const A & ) {}
};

int main() {
    throw A();
}

should be an error. But you simply should not be prohibiting copying of classes you want to throw as exceptions - why are you doing this?

Don't do it.

Consider this program:

#include <iostream>
#define X() (std::cout << __FUNCTION__ << "\n")

struct MyClass {
 MyClass() { X(); }
 ~MyClass() { X(); }
};

void f() {
 MyClass Obj;
 throw &Obj;
}

int main() {
 try {
  f();
 } catch(MyClass *a) {
  X();
 }
}

the output of which is this:

MyClass
~MyClass
main

Notice that the pointed-to object is destroyed before the program entered the catch block. This means that we must not dereference a in the catch block, severely limiting its usefulness.

The only way to avoid copying an exception object is to throw a pointer to the object, as you have done in your example. You must make sure that the object is static or heap allocated, not a local object that will disappear after leaving the code block during the throw.

Edit: Another approach comes to mind. You can create your own exception class (which should be derived from std::exception or one of its children) with the pointer as a member, then throw that. If you use a smart pointer such as shared_ptr you won't have to worry about the lifetime of the contained object.

It is syntactically correct and avoids the copy since the reference is being passed. But, usually an standard nameless exception object is constructed and is caught by the catch statement.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM