I am using Visual C++ 2005 (native C++)


For the following code, the different of main function 1 and main function 2 is
main function 1 using
}catch(MyException &e){
but main function 2 using
}catch(MyException e){

Which is more correct? if both are correct, which is better?

//========This is MyException.h=====
#pragma once
#include <string>
using std::string;
class MyException
{
public:
        MyException(void);
        MyException(string);
        virtual ~MyException(void);
        string getMsg(void);
 
private:
        string msg;
};
 
 
//=======This is MyException.cpp========
#include "MyException.h"
 
MyException::MyException(void):msg("")
{
}
MyException::MyException(string exceptionMsg):msg(exceptionMsg)
{
        
}
string MyException::getMsg(){
        return msg;
}
 
MyException::~MyException(void)
{
}
 
//======this is main function 1=======
        try{
         int i=1;       
         throw MyException("sth wrong");
        }catch(MyException &e){
         cout<<e.getMsg()<<endl;
        }
 
//======this is main function 2======
        try{
         int i=1;       
         throw MyException("sth wrong");
        }catch(MyException e){
         cout<<e.getMsg()<<endl;
        }

Dani AI

Generated

Both forms in your original post will compile and, for the simple case you showed, both will print the message. As already pointed out, the idiomatic and safer approach is to catch exceptions by (const) reference — this avoids an unnecessary copy and preserves the dynamic type when a derived exception is thrown.

A concrete difference shows why this matters:

struct Base : std::exception {
    virtual const char* what() const throw() { return "Base"; }
};
struct Derived : Base {
    virtual const char* what() const throw() { return "Derived"; }
};

try { throw Derived(); } 
catch (Base e) { std::cout << e.what() << '\n'; }        // prints "Base" (sliced)
try { throw Derived(); } 
catch (const Base& e) { std::cout << e.what() << '\n'; } // prints "Derived"

Additional practical tips not yet in the thread: prefer throwing objects by value and catching by const reference; if you need standard compatibility, derive from std::exception and implement what() so library code can consume your errors; if you catch and intend to rethrow, use throw; to preserve the original exception object — throw e; makes a copy and can change the observable type. Keep exception classes small and copyable, avoid throwing raw pointers (ownership problems), and be careful not to let exceptions escape destructors during stack unwinding.

Summary: for ’s example change the handler to catch(const MyException& e) (as suggested), consider returning the message as a const std::string& from a const accessor to avoid copies, and use throw; when rethrowing.

in general prefer catching exceptions by reference rather than by value.
if the actual object thrown is of a derived class, catching by reference avoids slicing (virtual functions will behave polymorphicaly, the class can be abstract). it also has the minor performance advantage of avoiding the making of a copy of the object. and to be const-correct, unless your intent is to modify the exception object, catch by const reference.

class MyException
{
	public:
    // ...
		string getMsg(void) const ;
    // ...

};
 
// ...
 
string MyException::getMsg() const { return msg; }
 
// ... 

//======this is main function 1=======
    // ...
		catch( const MyException &e )
		{
			cout << e.getMsg() << endl ;
		}

also see:
More Effective C++: 35 More Ways to Improve Your Programs and Designs by Scott Meyers -
ITEM 13. Catch Exceptions by Reference.
http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.7

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.