2013-05-05 52 views
3

這是一個困擾我一段時間的問題,但找不到處理它的最佳方法。我試圖通過一個例子來展示這一點。C++命名空間和類層次結構

我正在開發一個包含許多類的圖形庫。一些類的相互關係「的一部分」,像這樣的3類:

namespace MyGraphicsLibrary 
{ 

class MatrixStack 
{ 

}; 

class Transform 
{ 
    MatrixStack mMatrixStack; 
}; 

class Renderer 
{ 
    Transform mTransform; 
}; 

} 

Renderer類是供用戶使用,但我不想讓他們看到TransformMatrixStack類時他們查找MyGraphicsLibrary。最後兩個班僅適用於Renderer班,不適合用戶使用。

這裏我試圖做兩件事情:

  1. 從用戶隱藏TransformMatrixStack類。

  2. 反映類的「部分」層次結構。

我嘗試了以下解決這個:

  1. 對我來說,最好的辦法是私有的嵌套類,因爲這將表明該嵌套類是私人用戶,也反映層次如果你只是看Renderer類聲明。以下後居然讓我不確定這是很好的解決方案:Pros and cons of using nested C++ classes and enumerations?

  2. 我試圖把TransformMatrixStack到名爲Private另一個命名空間。因此,查找MyGraphicsLibrary名稱空間的用戶將看到Private名稱空間只覆蓋所有不適合用戶的類。 這很好,但也有很多其他類具有相同的問題,並且我迅速填充Private命名空間的類與其他類沒有任何關係。 在這裏,我只能拿出醜陋的解決方案,如引入嵌套的命名空間:

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

也許我錯過這裏的東西,但你怎麼想哪一個是要走的路。 有沒有人有第三種方式?

回答

0

使用匿名命名空間:

namespace MyGraphicsLibrary 
{ 
    namespace 
    { 
     class MatrixStack 
     { 

     }; 

     class Transform 
     { 
      MatrixStack mMatrixStack; 
     }; 
    } 

    class Renderer 
    { 
     Transform mTransform; 
    }; 

} 
+0

謝謝你的時間,我去與jmihalicza雖然 – Avithohol 2013-05-06 15:17:09

2

可以使用PIMPL-(也稱爲不透明指針)成語。 帶帽子,您可以完全隱藏用戶的課程,方法如下:

在您的公共標題(在您的包含文件夾中)中: 渲染器。ħ

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隱藏。標題必須與真實的界面分開。

+0

謝謝你的時間弗拉德,我去與jmihalicza雖然 – Avithohol 2013-05-06 15:17:10