3

これは私をしばらく悩ませている質問ですが、それに対処する最善の方法を見つけることができませんでした. 私は例を通してこれを示そうとしています。

多くのクラスを持つグラフィック ライブラリを開発しています。一部のクラスは、次の 3 つのクラスのように、相互に「一部」の関係にあります。

namespace MyGraphicsLibrary
{

class MatrixStack
{

};

class Transform
{
    MatrixStack mMatrixStack;
};

class Renderer
{
    Transform mTransform;
};

}

このクラスRendererはユーザーが使用するためのものですがTransform、. 最後の 2 つのクラスはクラス専用であり、ユーザーが使用するものではありません。MatrixStackMyGraphicsLibraryRenderer

ここで私は2つのことをしようとしています:

  1. TransformMatrixStackクラスをユーザーから隠します。

  2. クラスの「 part-of」階層を反映します。

これを解決するために、次のことを試しました。

  1. 私にとっての最善の解決策は、ネストされたクラスがプライベートであり、Rendererクラス宣言を見るだけで階層を反映していることをユーザーに示すため、ネストされたプライベートクラスです。次の投稿は、実際にはそれが良い解決策であるかどうかを確信させてくれます:ネストされた C++ クラスと列挙を使用することの長所と短所?

  2. をという名前の別の名前空間に入れようとしましTransformた。そのため、ユーザーが名前空間を検索すると、ユーザー向けではないすべてのクラスをカバーする名前空間のみが表示されます。それは良いことですが、同じ問題を抱えた他の多くのクラスがあり、名前空間を互いに関係のないクラスですばやく埋めます。ここでは、ネストされた名前空間を導入するなど、醜い解決策しか思いつきませんでした。MatrixStackPrivateMyGraphicsLibraryPrivatePrivate

    namespace MyGraphicsLibrary
    {
        //private classes belonging to Renderer class
        namespace PrivateRenderer
        {
        class MatrixStack
        {
        };
    
            class Transform
            {
                MatrixStack mMatrixStack;
            };
        }
    
        //public classes for users
        class Renderer
        {
        Transform mTransform;
        };
    }
    

多分私はここで何かを見逃していますが、どちらが行くべきだと思いますか. 誰もが第3の方法を持っていますか?

4

3 に答える 3

2

PIMPL- (不透明ポインターとも呼ばれる) イディオムを使用できます。hat を使用すると、次の方法でクラスをユーザーから完全に隠すことができます。

パブリック ヘッダー (インクルード フォルダー内): Renderer.h

class RendererImpl; // forward declaration of internal render structure

//public classes for users
class Renderer
{
  public:
    Renderer();
    ~Renderer();
    // public interface comes here and delegates all calls to RendererImpl (have to be implemented in cpp)

  RendererImpl* renderer; // better use something like QScopedPointer here
};

cpp:

#include "RendererImpl.h" // your actual renderer that 

Renderer::Renderer()
:renderer(new RendererImpl)
{}
Renderer::~Renderer()
{
  delete renderer;
}

実装は、API から完全に隠されている場合があります。ヘッダーは、実際のインターフェイスから分離する必要があります。

于 2013-05-05T13:37:40.407 に答える
0

匿名の名前空間を使用します。

namespace MyGraphicsLibrary
{
    namespace
    {
        class MatrixStack
        {

        };

        class Transform
        {
            MatrixStack mMatrixStack;
        };
    }

    class Renderer
    {
        Transform mTransform;
    };

}
于 2013-05-05T13:36:28.843 に答える