1 2 3 4 5 6 7
|
try {
m_sender = new Sender( "COM1" );
} catch ( const PortError &e ) {
QMessageBox::information( this, "Error", QString( e.what() ) );
} catch ( ... ) {
QMessageBox::information( this, "Error", "Error: unknown exception" );
}
|
I see you didn't
delete m_sender
if the constructor throws. That's good because the compiler deletes it.... Wait.....
I mean you need to delete it because it was constructed...
Hmm. But it wasn't constructed because you threw an exception.... hey just what DOES this do??
Remember if you ever declare one of these as a static or global that you have to surround it with a
try..catch
block:
1 2 3
|
try {
static Sender s("com1");
} catch {
|
Uh. Wait. Will that work?? Won't
s
be defined and deleted inside that try block? Can you really do this at file scope? You have to right? I mean, how can you create one of these at file scope without it right? But it's code in a declaration block.
Hmm....
And what if you have a
Sender
it as a member of another class:
1 2 3 4 5 6 7 8
|
class MySender:
string name n;
Sender s;
OtherStuff os1;
MySender(const string &nm) :
name(n), s("com1"), os1("somedata") {;}
~MySender();
}
|
Now in the
MySender
destructor you have to be careful because if the
Sender
member's contructor throws an exception then the other members aren't constructed.... I mean they get their default constructor... I mean unless OtherStuff's constructor throws, in which case....
uh......
Confused? Me too. :)
Issues like these are why it's a bad idea to throw exceptions in a constructor. It can be done, and there are well defined semantics for what happens in the cases I've described. But do you know the rules? Will the next person who sees your code know the rules? I know I don't.
So unless there is a compelling reason why you
need to throw in the constructor, I'd avoid it. Create an open() method instead. It makes the class more flexible and useable.