Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将基类初始化期间获得的信息存储在派生类中?_C++_Refactoring_Initialization Order - Fatal编程技术网

C++ 如何将基类初始化期间获得的信息存储在派生类中?

C++ 如何将基类初始化期间获得的信息存储在派生类中?,c++,refactoring,initialization-order,C++,Refactoring,Initialization Order,我的情况是,作为使用数据初始化基类的副作用,派生类计算一段信息,这些信息以后必须通过其接口可用。下面使用布尔值作为所需信息,给出了问题的思路: class base { public: base(some_initialization_data); // ... }; class derived : public base { public: derived() : base(calc_init_data()) { } bool condition_x_occu

我的情况是,作为使用数据初始化基类的副作用,派生类计算一段信息,这些信息以后必须通过其接口可用。下面使用布尔值作为所需信息,给出了问题的思路:

class base {
public:
  base(some_initialization_data);
  // ... 
};

class derived : public base {
public:
  derived()
  : base(calc_init_data())
  {
  }

  bool condition_x_occurred() const
  {
    // How to get at the information obtained 
    // during the call to calc_init_data()? 
  }
private:
  static some_initialization_data calc_init_data()
  {
    // This piece of information will later be needed: 
    const bool condition_x_occurred = /* ... */;
    return some_initialization_data(condition_x_occurred);
  }
};
这样做的问题是,在初始化基类期间,在初始化派生类自己的数据成员之前,会计算重要的信息。因此,我还不能写入派生类的数据元素。虽然我确信我可以摆脱在过去20年中遇到的任何平台上尚未正式创建的布尔值,但我希望避免调用未定义的行为

请注意,所讨论的信息与基类没有任何关系,因此将其存储在基类中是没有选择的。此外,信息不能存储在静态数据成员中。我有一些关于如何重构代码的想法,这样我就可以做到这一点,但是对于这样一个小问题,我能想到的那些想法似乎都是相当侵入性的。所以我想知道你们中是否有人能想出一些简单的办法



注意:因为我们在嵌入式平台上,所以我们只能使用GCC4.1.2。严格来说,C++03(包括TR1),但没有C++11

在C++11中,您可以执行以下操作:

class derived : public base {
public:
  derived() : derived(calc_init_data()) {}

  bool condition_x_occurred() const { return my_condition_x_occurred; }

private:
    derived(const std::pair<bool, some_initialization_data>& p) :
        base(p.second), my_condition_x_occurred(p.first)
    {}

  static std::pair<bool, some_initialization_data> calc_init_data()
  {
    // This piece of information will later be needed:
    const bool condition_x_occurred = /* ... */;
    return std::make_pair(condition_x_occurred, some_initialization_data(condition_x_occurred));
  }

private:
    bool my_condition_x_occurred;
};
class derived : public base {
public:
  static derived make_derived() { return derived(calc_init_data()); }

  bool condition_x_occurred() const { return my_condition_x_occurred; }

private:
    derived(const std::pair<bool, some_initialization_data>& p) :
        base(p.second), my_condition_x_occurred(p.first)
    {}

  static std::pair<bool, some_initialization_data> calc_init_data()
  {
    // This piece of information will later be needed:
    const bool condition_x_occurred = /* ... */;
    return std::make_pair(condition_x_occurred, some_initialization_data(condition_x_occurred));
  }

private:
    bool my_condition_x_occurred;
};
派生类:公共基{
公众:
派生():派生(calc_init_data()){}
bool condition_x_occurrent()常量{return my_condition_x_occurrent;}
私人:
派生(常量标准::对和对):
基本(第二页),我的情况发生(第一页)
{}
静态std::pair calc_init_data()
{
//稍后将需要此信息:
常量布尔条件_x_发生=/*…*/;
return std::make_pair(发生条件_x_,一些条件初始化_数据(发生条件_x_));
}
私人:
bool我的情况发生了;
};
在C++03中,您可以将派生类更改为:

class derived : public base {
public:
  derived() : derived(calc_init_data()) {}

  bool condition_x_occurred() const { return my_condition_x_occurred; }

private:
    derived(const std::pair<bool, some_initialization_data>& p) :
        base(p.second), my_condition_x_occurred(p.first)
    {}

  static std::pair<bool, some_initialization_data> calc_init_data()
  {
    // This piece of information will later be needed:
    const bool condition_x_occurred = /* ... */;
    return std::make_pair(condition_x_occurred, some_initialization_data(condition_x_occurred));
  }

private:
    bool my_condition_x_occurred;
};
class derived : public base {
public:
  static derived make_derived() { return derived(calc_init_data()); }

  bool condition_x_occurred() const { return my_condition_x_occurred; }

private:
    derived(const std::pair<bool, some_initialization_data>& p) :
        base(p.second), my_condition_x_occurred(p.first)
    {}

  static std::pair<bool, some_initialization_data> calc_init_data()
  {
    // This piece of information will later be needed:
    const bool condition_x_occurred = /* ... */;
    return std::make_pair(condition_x_occurred, some_initialization_data(condition_x_occurred));
  }

private:
    bool my_condition_x_occurred;
};
派生类:公共基{
公众:
静态派生make_-derived(){return-derived(calc_init_-data());}
bool condition_x_occurrent()常量{return my_condition_x_occurrent;}
私人:
派生(常量标准::对和对):
基本(第二页),我的情况发生(第一页)
{}
静态std::pair calc_init_data()
{
//稍后将需要此信息:
常量布尔条件_x_发生=/*…*/;
return std::make_pair(发生条件_x_,一些条件初始化_数据(发生条件_x_));
}
私人:
bool我的情况发生了;
};

如果在编译器上可用,则可以使用委托构造函数:

struct derived_init
{
    bool data;
    some_initialization_data calc()
    {
        data = true;
        return some_initialization_data();
    }
};


class derived : public base {
public:
    derived()
        : derived(derived_init{})
    { }

    bool condition_x_occurred() const
    {
        return init_data.data;
    }
private:
    derived(derived_init init)
        : base(init.calc()), init_data(init)
    { }
    derived_init init_data;
};
对于C++03,可以使用默认参数:

class derived : public base {
public:
    derived(derived_init init = derived_init{})
        : base(init.calc()), init_data(init)
    {
    }
private:
    derived_init init_data;
};

听起来好像有什么办法可以解决。@Angew:偷偷加入另一个基类也是我最喜欢的解决方案,尽管我觉得有点麻烦。我不知道boost有这个功能,我觉得它很有趣。但是,我不确定使用它而不是简单的基类是否会使代码更易于阅读和维护。不过我可以试试。你为什么不回答这个问题?它值得投票表决。我从未使用过它,所以我不能自信地在答案中给出一个例子。我不喜欢只链接的答案。对不起,我忘了提到我们一直使用C++03。这里没有授权人<代码>:(很好的解决方案,但是,非常不具侵入性。
+1
来自我。@sbi可能默认参数适合您?请参见编辑。抱歉,我忘了提到我们一直使用C++03。根本没有C++11。这也是基于委托的。很好,它使用了
std::pair
。另一个
+1
来自我。您可以使用factory吗(伪造委托构造函数)?是的,我可以。但是,这属于“相当侵入性”。
:-/
请参见我的编辑。(但是@hansmad的默认参数解决方案似乎更好)。