web-dev-qa-db-ja.com

相互に関連するクラスのシステムを作成するにはどうすればよいですか?

私は自分が使用するC++ glfwラッパーを作成しています。 _GLFWMonitor*_や_GLFWWindow*_などのglfwオブジェクトのラッパーであるMonitorWindowContextなどのクラスが欲しい。問題は、Windowクラスにメソッドcreate_window()が必要な場合、Monitorクラスの基になる生のglfwポインターにアクセスできる必要があることです。同時に、Monitorクラスにenumerate_windows()のようなメソッドが必要な場合は、基になるglfwウィンドウポインターにアクセスする必要があります。両方のクラスでパブリックメソッドget_raw_handle()を使用することもできますが、実装の詳細は非表示になっているため、ユーザーがこの情報にアクセスできないようにする必要があります。ライブラリでのみ使用できます。

クラスを相互にfriendできると思ったが、それは正しくないようで、まるで新しいクラスを追加したい場合は、既存のすべてのクラスをfriendする必要があるだろうそしてその逆。また、すべてに対してフォワード宣言が必要であり、現在のところ、私のライブラリはヘッダーのみです。

また、これらのオブジェクトはすべて、WindowingSystemObjectメソッドget_raw_handle()を持つスーパーprotectedクラスから継承できると考えましたが、これはハンドルに(_void*_のように)ユニバーサルにしてから、適切な型にキャストします。

これはすべて非常に複雑に見えます。コードを書く代わりに、私はある種の哲学者のように感じます。 C++(クラス付き)で作成する必要があるのか​​、それともCで作成する必要があるのか​​、それが機能する限りカプセル化について気にする必要はありません。

問題は、Windowクラスにcreate_window()メソッドが必要な場合、Monitorクラスの基になる生のglfwポインターにアクセスできる必要があることです。

これは実際には問題ではありません。各オブジェクトについて、他のオブジェクトとは何の関係もない、隔離されたロックされたものであるかのように考えています。

しかし、ラップしようとしているAPIは別のことを言っています。

GLFWウィンドウを作成する行為は、モニターを利用することができます。そのため、2つのオブジェクトは自然に関連しています。したがって、2つのオブジェクトが、外の世界がそれらと対話するために使用できない方法で互いに対話することは、完全に理にかなっています。

同時に、Monitorクラスにenumerate_windows()のようなメソッドが必要な場合は、基になるglfwウィンドウポインターにアクセスする必要があります。

なんで?私の知る限りでは、GLFWはGLFWwindowごとのGLFWmonitorsのリストを保存していません。したがって、Monitorクラスが列挙可能なウィンドウのリストを格納する場合は、Windowポインタではなく、GLFWwindowラッパーのリストを格納する必要があります。

両方のクラスでパブリックメソッドget_raw_handle()を使用することもできますが、実装の詳細は非表示になっているため、ユーザーがこの情報にアクセスできないようにしたいと思います。

確かですか?最初の文で、「私は自分が使用するC++ glfwラッパーを作成しています」と述べました。これは、GLFWまたは他のAPIを介して実装できる任意の抽象化を行うこととは非常に異なるプロジェクトです。前者は、定義により、GLFWが存在し、使用されていることを前提としています。

また、ライブラリがヘッダーのみになる場合は、ライブラリを含むすべての人がライブラリを含めるときに、使用している基になるシステムを非表示にするのはreally hardです。作成したもの、つまりGLFWラッパーだけを所有するのが最善です。

最後に、GLFWをライブラリのインターフェイスの一部にすることで(存在しないふりをしようとするのではなく)、GLFWが変更されると、ライブラリを更新してラッパーを追加する前に、ユーザーは新しいGLFW APIを使用できます。

新しいクラスを追加したい場合と同じように、既存のすべてのクラスをそのクラスと友だちにする必要があります。

ナンセンス。関係が必要な範囲で関係を追加します。 Windowは、MonitorからGLFWタイプを抽出できる必要があります。しかし、MonitorWindowに対してそれを行う必要はありません。

1
Nicol Bolas