仿真课程设计

时间:2013-05-14 16:18:41

标签: c++ oop

我正在寻找用户使用非常复杂的初始条件进行模拟。我正在编写class A,其成员变量需要由用户初始化,然后才能运行A.Solve()以将结果存储在文件中。初始化相当复杂,需要在初始化后不再需要的几个临时数据结构。所以,我编写了另一个名为class Initializer的类,它存储了对class A对象的引用。我的代码看起来像这样:

 class A {
   friend class Initializer;
   private:
     // member variables storing the state of the system
   public:
     void Solve();
     ...
 };

 class Initializer {
   private:
     A& a
     // Other data structures used in the initialization
     ...
   public:
     // functions called by the user to set up for the initialization
     ...
     Initialize(); // after this is called, a will be ready to solve
 };

 int main(...) {
   A a;
   Initializer init(a);
   // call functions on init to initialize the system
   ...
   init.Initialize();
   a.Solve();
   return 0;
 }

但似乎init中的数据结构将存在于整个程序的堆栈中。为了防止这种情况,可以这样做:

  A a;
  Initializer *init = new Initializer(a);
  ....
  init.Initialize();
  delete init;
  a.Solve();

或者这看起来不必要,我应该只包含class A中的所有内容吗?

2 个答案:

答案 0 :(得分:1)

要回答您的原始思路,通常的解决方案是限制init变量的范围:

A a;
{
    Initializer init(a);
    //...
} // init is destroyed as soon as the scope exits
a.Solve();

您的new/delete变体非常脆弱,如果在newdelete之间抛出任何内容,则会泄漏内存。要解决这个问题,请使用智能指针:

A a;
std::unique_ptr<Initializer> init(new Initializer(a));
//...
init.reset();
a.Solve();

然而正如其他人所说的那样,这整个设计有点奇怪,而且可能有点过分。如果初始化真的那么复杂,你无法摆脱构造函数,那么你可能想要反过来做:而不是Initializer采用参数A并对其进行操作,你应该传递一个完全可以使用的InitializerA的构造函数,它将复制整个Initializer以保留数据的副本,或者只复制相关的位。然后,Initializer可能会重命名为Config或类似的内容。请注意现在如何重用Config/Initializer对象来初始化多个A对象,甚至可以在两个A初始化之间进行修改。

不幸的是,很难用如此少的信息给你明确的建议。

注意:如果您使用C ++ 11,您可能会对std::initializer_list感兴趣,它会启用新的大括号初始化语法。根据数据的复杂程度,它可能涉及比当前解决方案更多的工作,但最终会得到非常好的直观语法。

答案 1 :(得分:0)

在这里,使用另一个类进行初始化目的似乎有点矫枉过正。

只需在A类构造函数中初始化。 构造函数执行完成后,临时数据结构将自动释放。