Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
442 views
in Technique[技术] by (71.8m points)

templates - How can I abstract out a repeating try catch pattern in C++

I have a pattern that repeats for several member functions that looks like this:

int myClass::abstract_one(int sig1)
{
  try {
    return _original->abstract_one(sig1);
  } catch (std::exception& err) {
    handleException(err);
  } catch (...) {
    handleException();
  }
}

bool myClass::abstract_two(int sig2)
{
  try {
    return _original->abstract_two(sig2);
  } catch (std::exception& err) {
    handleException(err);
  } catch (...) {
    handleException();
  }
}

[...]

int myClass::abstract_n(bool sig3a, short sig3b)
{
  try {
    return _original->abstract_n(sig3a, sig3b);
  } catch (std::exception& err) {
    handleException(err);
  } catch (...) {
    handleException();
  }
}

Where abstract one through n are methods of a pure virtual abstract interface for which myClass and _original are concrete implementations.

I don't like that this pattern repeats in the code and would like to find a way to eliminate the repeating try / catch pattern and code as a single abstraction, but I can't think of a good way to do this in C++ without macros. I would think that there is a way with templates to do this better.

Please suggest a clean way to refactor this code to abstract out the repeated pattern.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I asked a very similar conceptual question, see Is re-throwing an exception legal in a nested 'try'?.

Basically, you can move the various exception handlers to a separate function by catching all exceptions, calling the handler and rethrowing the active exception.

void handle() {
 try {
  throw;
 } catch (std::exception& err) {
   handleException(err);
 } catch (MyException& err) {
   handleMyException(err);
 } catch (...) {
   handleException();
 }
}

try {
   return _original->abstract_two(sig2);
} catch (...) {
   handle();
}

It scales well with more different exception kinds to differenciate. You can pack the first try .. catch(...) into macros if you like to:

BEGIN_CATCH_HANDLER
return _original->abstract_two(sig2);
END_CATCH_HANDLER

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...