Try/catch absurdity and calling destructors...

Started by
20 comments, last by Bruno Sofiato 11 years, 3 months ago

Yodas are only useful when you're comparing to a retval by putting a long function in the clause:


if(S_OK != BigLongComFunctionNameISawMicrosoftDoThisInSomeOfTheirPublicHeaders(thingy, &otherThingyPtr)) {
  //shimatta
}

After seeing that in the MS header I thought, "Aha!" I used the same method myself like twice and then I was like, "Shouldn't I just catch the retval in a variable and compare the variable so that people can actually read this?"

Concerning OP, using smart pointers is really very handy for stuff like that and they are tailored for that kind of usage (with RAII and the strong guarantee in mind). You can have a smart pointer belonging to the class:

std::unique_ptr<RscType> m_resourcePtr;

Then in the ctor:


std::unique_ptr<RscType> resource;
resource.reset(someFuncThatReturnsARscPtrOrNull(arg));
if(resource.get() == NULL) {
  //failure
  return; //or throw - see next para
}

//once all resources are loaded to function-local smart pointers:
m_resourcePtr = resource;
//That syntax will _transfer_ control from the function-owned unique_ptr to the object-owned one.

It can make things a lot smoother. You'll like it. smile.png

Meanwhile, a constructor can't return a value, so throwing an exception is the only way to communicate internal errors. Why not let your exceptions leave the ctor and catch them at the next point where you can actually handle them?

For instance, you had:


     try{
          ptr2 = new int(some_val);
     }
     catch(bad_alloc)
     {
          some_class::~some_class();
          std::cout << "Unable to allocate memory." << std::endl;
          return; // Skip the rest of the constructor.
     }

But if you're using smart pointers then you can just allow the bad alloc to break out of the ctor and catch it from the context that's called the ctor. In this way you can communicate other error types by throwing a std::runtime_error("string description") from your ctor. Just catch those in the same place and then you can fetch the description like so:


Foo* fooObj;
try {fooObj = new Foo;}
catch(bad_alloc) { //also catches bad_alloc's from inside the ctor
  cout << "I jes cannae do it cap'n. I don't hae the memory!" << endl;
  return -1;
}
catch(runtime_error &err) {
  cout << err.what() << endl;
  return -1;
}
void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.
Advertisement

In Java, it's considered a good pratice to use yoda style comparation when comparing to a non primitive constant using the equals() method. It's garanteed that the constant never will be null, so you could get away with a null checking.

This topic is closed to new replies.

Advertisement