0

Pimplは「実装へのポインター」の略で、クラス内の実装を隠す便利な方法を提供します。このクラスのユーザーからプラットフォーム固有の関数と構造を隠す Window クラスを実装しているため、クラス インターフェイスは非常にきれいに見えます。

class Window{
public:
    /// Constructors & destructors:
    Window(void);
    Window(Window const& window_);
    Window(Window&& window_);
    explicit Window(std::string const& title_);
    explicit Window(std::string&& title_);
    ~Window(void);
    /// Member data:
    bool visible = false;
    ContextGraphics graphics_context;
    std::array<unsigned long, 2> position = {{0}}, size = {{800, 600}};
    std::string title;
    /// Member functions:
    void apply_changes(void);
    Window& center_position(void);
    bool enabled(void) const;
    void update(void);
    /// Member functions (overloaded operators, assignment):
    Window& operator=(Window const& window_);
    Window& operator=(Window&& window_);
private:
    /// Inner classes:
    class Helper;
    /// Member data:
    std::unique_ptr<Window::Helper> _m_opHelper;
};

舞台裏には厄介な WINAPI 呼び出しなどがあります。サポートされるプラットフォームの範囲を広げることを目指している場合は、クラス ヘッダーを変更する必要はまったくなく、ソース ファイルのみを変更する必要があります。とても便利で、そんなに書き直す必要はありません!

ただし、このオブジェクトは私の問題のようです(クラス内):

ContextGraphics graphics_context;

これは Direct3D/OpenGL グラフィックス コンテキスト ( 「ContextGraphics」のユーザーが決定できます) であり、ご想像のとおり、pimpl-idiom も使用します。

class ContextGraphics{
    /// Friends:
    friend class Window;
public:
    /// Enumerations:
    enum class API : unsigned int{
        API_DEFAULT,
        API_DIRECT3D,
        API_OPENGL
    };
    /// Constructors & destructors:
    ContextGraphics(void);
    explicit ContextGraphics(ContextGraphics::API const& api_);
    explicit ContextGraphics(ContextGraphics::API&& api_);
    ~ContextGraphics(void);
    /// Member data:
    ContextGraphics::API api = ContextGraphics::API::API_DEFAULT;
    unsigned int color_depth : 6; // 2 ^ 6 = 64
    /// Member functions:
    bool api_available(void) const noexcept;
    bool enabled(void) const;
    /// Member functions (overloaded operators, assignment):
    ContextGraphics& operator=(ContextGraphics const& context_graphics_);
    ContextGraphics& operator=(ContextGraphics&& context_graphics_);
private:
    /// Constructors & destructors:
    ContextGraphics(ContextGraphics const& context_graphics_);
    ContextGraphics(ContextGraphics&& context_graphics_);
    /// Inner classes:
    class Helper;
    /// Member data:
    std::unique_ptr<ContextGraphics::Helper> _m_opHelper;
    /// Member functions:
    void create(void);
    void destroy(void);
};

私が直面している問題はコンパイラです:

Window.cpp|145|エラー: 不完全なタイプ 'クラス ContextGraphics::Helper' の無効な使用|

ContextGraphics.hpp|43|エラー: 'クラス ContextGraphics::Helper' の前方宣言|

コンパイラは、クラス「ContextGraphics::Helper」の実装を見つけられないようです。これは、pimpl を含むクラスが pimpl を含むオブジェクトをまったく使用できるかどうかという問題を提起するだけです。すべての実装を Window クラスのソース ファイル内に配置せずにこれを行うことは可能ですか? 私には、それは合理的な解決策ではないようです。

4

1 に答える 1