C++(或任何其他语言)的优雅控制流程

Yog*_*rma 2 c++

我正在编写一个具有许多返回点的函数(取决于条件是什么),它new在不同的点上做了很多.在每个返回点,delete我需要做的一组是不同的.即便如此,我也不想在不同的地方做这些.处理这个问题的好方法是什么?

一些细节:让我们考虑一个功能:

int MainClass::testFunction() {
  numThreads++;
  char *a = new char[100];
  // Some computation with a
  if (condition1) {
    numThreads--;
    return -1;
  } 
  char *b = new char[100];
  // Some computation with b
  if (condition2) {
    numThreads--;
    return 42;
  } 
  // Some more stuff. 
  numThreads--;
}
Run Code Online (Sandbox Code Playgroud)

现在,之前return -1,我需要做的delete a而在此之前return 42,我需要做的delete a; delete b;.如果我有多个返回点,你可以想象这会变得多么复杂.

这是我的解决方案:

第一种解决方案:将所有删除放在函数末尾,放置一些标签,将返回值存储在返回点,然后使用goto(是的,那个脏字!)跳转到适当的删除并在执行删除后返回.

在上面的例子中,我可以说

superset:
  delete b;
subset:
  delete a;
numThreads--;
Run Code Online (Sandbox Code Playgroud)

并放在goto superset之前return 42goto subset之前return -1.

我出于明显的原因不喜欢这个解决方案!:-)

第二个解决方案:我可以构建一个内部类实例,并对该类实例的new变量进行操作.像这样...

int MainClass::testFunction() {
  class Local {
    char *a, *b;
    Local () : a(NULL), b(NULL) {}
    ~Local () { if (a != NULL) delete a; if (b != NULL) delete b; }
  };
  Local l = Local();
  l.a = new char[100];
  // Some computation with a
  if (condition1) {
    return -1;
  } 
  l.b = new char[100];
  // Some computation with b
  if (condition2) {
    return 42;
  } 
}
Run Code Online (Sandbox Code Playgroud)

那么,问题是什么?那么,我如何访问方法中的numThreads变量?我想numThreads++在构造函数中LocalnumThreads--在函数中执行Local.如果它有帮助,testFunction也是另一个类的成员函数.

谢谢阅读.

更新:在堆栈上分配数组肯定是一种可能性,但我遇到了堆栈溢出(啊...这个网站的名称:-))在堆栈上进行大量分配(默认情况下,线程的堆栈大小为2MB).我想在这个问题中解决的是一般资源获取和销毁.

Cli*_*ton 9

了解RAII

基本上,new除了在构造函数(或赋值)之外,永远不要使用,delete除了在析构函数中之外永远不要使用.

关于您的具体情况,您可以执行以下操作:

(1)只需使用std::vector<char>.
(2)char a[100];改为(这是堆栈分配,因此自动收集).这只有100在常数时才有效.您也可以使用std::array<char, 100>C++ 11编译器(或者boost::array<char, 100>如果安装了boost库).
(3)用于alloca()在堆栈上分配空间(如果100不是常量)(注意这一点).
(4)编写自己的类,new在构造函数中使用分配内存,并delete在析构函数中删除内存.

我建议(2)如果100是常数而不是太大,否则(1).