コンストラクターですべての内部メンバーを初期化できないクラスを設計する方法を理解するのに苦労しています。これが基本的なものであり、ネット上で議論されるべきであることはわかっていますが、何を探すべきかわかりません。したがって、たとえば、次のコードを検討してください。
#include <iostream>
class Workhorse
{
public:
void SetData (const int &data)
{
this->data = data;
}
int GetData () const
{
return this->data;
}
private:
int data;
};
class Worker
{
public:
Worker ()
{
}
void Initialize (const int &data)
{
horse.SetData(data);
}
void Action () const
{
std::cout << horse.GetData() << std::endl;
}
private:
Workhorse horse;
};
int main ()
{
Worker worker;
worker.Initialize(3);
worker.Action();
return 0;
}
最初に Initialize() を呼び出さずにワーカーがメソッドを呼び出さないようにしたい。素人の実装は、Worker クラスに isInitialized フラグを追加し、Initialize() でそれを true に設定し、各パブリック メソッドの先頭でテストすることです (継承を導入する場合は、プロテクト / プライベート メソッドでも同様でしょうか?) . 残念ながら、これは少し面倒で、維持するのが難しいようです。また、すべてのメソッドで if ステートメントを繰り返すのはひどいことです。スレッド セーフの問題について考え始めたわけではありませんが、現在はシングル スレッドのアプリケーションしか実装していません。これを設計するよりスマートな方法はありますか?
編集:OK、私は例としてダムデザインを選びましたが、実際には欠陥があります. 私が持っているものをより明確に示してみましょう:
#include <iostream>
class PublicKeyCryptoProvider
{
public:
struct PublicKey
{
int shared;
};
struct PrivateKey
{
int secret;
};
int Encrypt (const int &plaintext) const
{
int ciphertext;
//apply encryption algorithm on plaintext
ciphertext = plaintext * this->pk.shared;
return ciphertext;
}
int Decrypt (const int &ciphertext) const
{
int plaintext;
//apply decryption algorithm on ciphertext
plaintext = ciphertext / this->sk.secret;
return plaintext;
}
void GenerateKeys ()
{
this->pk.shared = 4;
this->sk.secret = 4;
//generate pk and sk
}
void SetPublicKey (const PublicKey &pk)
{
this->pk = pk;
}
const PublicKey &GetPublicKey () const
{
return this->pk;
}
private:
PublicKey pk;
PrivateKey sk;
};
int main ()
{
/* scenario 1: */
PublicKeyCryptoProvider cryptoProvider;
cryptoProvider.GenerateKeys();
std::cout << cryptoProvider.Decrypt(cryptoProvider.Encrypt(3)) << std::endl;
/* /scenario 1: */
/* scenario 2: */
PublicKeyCryptoProvider cryptoProvider1;
cryptoProvider1.GenerateKeys();
PublicKeyCryptoProvider cryptoProvider2;
cryptoProvider2.SetPublicKey(cryptoProvider1.GetPublicKey());
int ciphertext = cryptoProvider2.Encrypt(3);
std::cout << cryptoProvider1.Decrypt(ciphertext) << std::endl;
//now let's do something bad...
std::cout << cryptoProvider2.Decrypt(ciphertext) << std::endl;
/* /scenario 2: */
return 0;
}
明らかに、シナリオ 2 が完全に有効な実際の例を想像できます。上記の状況を考えると、PublicKeyCryptoProvider クラス内に canDecrypt フラグを追加するよりも良いオプションはありますか? これは非常に単純な例であることに言及する必要があります。私の場合、PublicKeyCryptoProvider が秘密鍵の所有者であり、公開メソッドがはるかに多い場合、PublicKeyCryptoProvider はより高速な暗号化を実行できるため、フラグをテストする運命にあるからです。数回以上...また、サーバーがクライアント用のパブリックメソッドの束を公開するクライアント-サーバーモックアップシナリオがありますが、クライアントは Initialize() メソッドを呼び出した後にのみメソッドを呼び出すことができますサーバー...