1

我经常要面对一个类包含多个 const 变量的场景,这些变量需要在初始化列表中进行初始化,而且还需要提前一些其他的方法来计算值。

例如,对于以下类:

class Base
{
    protected:
        const int a, b;
    public:
        Base(string file);
};

我希望构造函数通过解析文件来提取一些变量,然后将提取的值分配给 const 变量(ab)。我以前经常破坏逗号运算符(使用逗号运算符来初始化基类),但发现对于更复杂的情况非常不方便。关于一些更优雅的解决方案的任何建议?

4

1 回答 1

5

在需要解析一个对象来计算一个数据成员的值的简单情况下,我会提供一个免费函数并调用它:

int ComputeAFromFile (const string& file)
{
  // MAGIC
}

class Base
{
    protected:
        const int a;
    public:
        Base(string file) : a (ComputeAFromFile (file)) {}
};

但是,当您需要解析一个对象来计算多个成员的值时,这种情况就会崩溃:

int ComputeAFromFile (const string& file)
{
  // MAGIC
}

int ComputeBFromFile (const string& file)
{
  // MORE MAGIC
}


class Base
{
    protected:
        const int a, b;
    public:
        Base(string file) 
  : 
    a (ComputeAFromFile (file)) 
    b (ComputeBFromFile (file)) 
  {
  }
};

您可以这样做,而且它当然很简单(阅读:易于理解和维护),但在必须两次解析同一个文件方面也很昂贵。

所以相反,我经常做的是构建一种中间对象,它在构建时解析文件一次,并缓存提取的值:

class FileParser 
{
public:
  FileParser (const string& file)
  {
    Parse (file);
  }

  int GetA () const { return mA; }
  int GetB () const { return mB; }

private:
  int mA;
  int mB;

  void Parse (const string& file)
  {
    // MAGIC HAPPENS!
    // Parse the file, compute mA and mB, then return
  }
};

现在,它可以采用 a ,而不是Base采用 a构造:stringFileParser

class Base
{
public:
  Base (const FileParser& parser)
  :
    a (parser.GetA()),
    b (parser.GetB())
  {
  }
};

Base 是这样构造的:

string file = ...;
Base b (FileParser (file));
于 2013-10-16T19:35:22.430 回答