【发布时间】:2013-07-21 09:27:22
【问题描述】:
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|错误:无效使用不完整类型 'class ContextGraphics::Helper'|
ContextGraphics.hpp|43|错误:'class 的前向声明 ContextGraphics::Helper'|
编译器似乎没有找到类“ContextGraphics::Helper”的实现,这只会引发一个问题,即带有 pimpl 的类是否可以使用带有 pimpl 的对象。如果不将所有实现都放在 Window 类源文件中,是否可以这样做?对我来说,这似乎不是一个合理的解决方案。
【问题讨论】:
-
你遇到了一个普通的循环依赖问题。在这个网站和其他网站上有大量关于此的信息。 Pimpl 与它无关。
-
@Mat:哦,很高兴为这个问题起个名字。谢谢!这有助于找到可能的解决方案,如果确实存在的话。
-
好吧,问题仍然存在——这可能吗?如果可以,怎么做?
标签: c++11 forward-declaration unique-ptr pimpl-idiom