基本クラスの初期化中に取得された派生クラス情報に格納できますか?
-
21-12-2019 - |
質問
基本クラスを初期化するためのデータを起動することの副作用として、派生クラスはそのインタフェースを介して後で利用可能でなければならない情報を計算します。以下は、情報が望んでいるようにブール値を使用して問題の考えを示します。
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年間で終わったプラットフォームでまだ正式に作成されていないブール値を逃れることができると確信していますが、未定義の動作を呼び出すことを避けたいと思います。
基本クラスではまったく関係ありませんので、基本クラスに保存することはオプションです。また、情報を静的データメンバーに格納することはできません。私はこれを行うことができるようにコードをリファクタリングする方法についてのアイデアがいくつかありますが、私がそのような小さな問題のために非常に邪魔になるようです。だから私はあなたの一人が簡単なことを思い付くことができるのだろうか?
注 :埋め込みプラットフォームにいるので、GCC 4.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;
};
.
C ++ 03では、派生クラスを次のようなものに変更することができます。
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;
};
. 他のヒント
コンパイラで利用可能な場合は、委任コンストラクタを使用できます。
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;
};
. 所属していません StackOverflow