カプセル化と「言うな、聞くな」という原則を適切に使用する場合、オブジェクトから情報を求める理由はないはずです。ただし、クラス外の関数を指すメンバー変数を持つオブジェクトがある状況に遭遇しました (この設計自体がひどい場合はお知らせください)。
アプリケーションのある時点で、オブジェクトが関数を呼び出す必要があり、関数はオブジェクトのステータスに基づいて動作する必要があります。
クラスの例を次に示します。
typedef void(*fptr)(Foo*);
class Foo {
public:
Foo(string name, fptr function);
void activate()
{
m_function(this);
}
private:
string m_name;
fptr m_function;
};
これがクラスです。開発者はクラスを次のように使用できます。
void print(Foo *sender)
{
cout << "Print works!" << endl;
}
int main(int argc, char **argv)
{
Foo foo("My foo", &print);
foo.activate();
// output: "Print works!"
}
これで問題なく動作しますが、送信者の名前を印刷したい場合はどうすればよいでしょうか? すべての関数は、他の開発者によってクラスの外部で定義されているため、プライベート変数にアクセスする方法はありません。では、キーワードをC#
使用して既存のクラスにメソッドを追加できます。partial
ただし、これは不可能C++
です。
カプセル化を無視して、セッターとゲッター、name
および将来関数で必要になる可能性のあるその他すべてのプロパティを作成できます。これはかなりひどい解決策です。関数はオブジェクトに対して何でもできるので、基本的にクラスにあるすべてのものに対してセッターとゲッターを作成する必要があります。カプセル化の理由に加えて、必要なときに無視する場合はどうすればよいですか?
他の解決策は、必要なプロパティを内部に保持する構造体です。
struct FooBar {
string name;
};
typedef void(*fptr)(FooBar);
void Foo::activate()
{
FooBar fb;
fb.name = m_name;
m_function(fb);
}
しかし、これはカプセル化を使用しないことと大差ありませんし、あまり良い解決策にも思えません。この問題に対する最善のアプローチは何でしょうか?