Jump to content

  • Log In with Google      Sign In   
  • Create Account


Try/catch absurdity and calling destructors...


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
21 replies to this topic

#21 Khatharr   Crossbones+   -  Reputation: 2616

Like
0Likes
Like

Posted 29 December 2012 - 10:23 AM

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;
}

Edited by Khatharr, 29 December 2012 - 10:26 AM.

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.

Sponsor:

#22 Bubsy   Members   -  Reputation: 407

Like
1Likes
Like

Posted 29 December 2012 - 10:44 AM

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.






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS