は(意図的に不自然な例は以下の)2つのクラスが互いにデフォルトに構成又は構築することができる仮定のシナリオを検討が、いずれかの方法は、高価であると考えられている:コンストラクタの初期化リストは、
struct PrivateKey;
struct PublicKey {
PublicKey(); // generate a random public key (1 minute)
PublicKey(const PrivateKey& b); // find a public key corresponding to a private key (1 year)
...members...
};
struct PrivateKey {
PrivateKey(); // generate a random private key (1 minute)
PrivateKey(const PublicKey& a); // find a private key corresponding to a public key (1 year)
...members...
};
(これはもちろん1つのクラスに凝縮することができますが、質問の妥当性は影響を受けません。一貫性のために、一方と他方の間に対称性がないとしましょう)
ここでは両方のインスタンスとニーズを保持する構造体がありますこのクロス初期化。しかし、両方向が必要な場合があるので、イニシャライザーリストでは実際には切り取ることができません(リストされた順序ではなく、メンバーが定義された順序で実行されます)。
struct X {
PublicKey a;
PrivateKey b;
X(int): a(), b(a) { }
X(float): b(), a(b) { } // UB: a(b) happens before b is initialized
};
もちろん
私は試みることができる:
struct X {
PublicKey a;
PrivateKey b;
X(int): a(), b(a) { }
X(float): a(), b() { a = PublicKey(b); }
};
をしかし、これははすぐに結果だけをスローするX
の第二のコンストラクタでPublicKey
の高価なデフォルト・建設を実行しているの複数の問題を、持っているだけで最初のものです。 副作用PublicKey::PublicKey()
からがあるかもしれません。どちらも、まだ一部だけダミー状態でクラスを置く友人X
にさらさ安いプライベートコンストラクタを作成することによって軽減することができますが、いくつかの参照または定数のメンバーで投げるとクラスが割り当て可能-移動したりをスワップ可能な禁止されない場合がありますX::X(float)
の体のバリエーション。それに続く良いパターンがありますか?
'PublicKey * a'と' PrivateKey * b'を使って、それらをコンストラクタ本体 '{...}'の内部に構築します。 – AJNeufeld
@AJNeufeld答えは下にあります。 – NathanOliver
クリスタルクリア。私は何を考えていたの?回答を投稿するためのケア? –