Pimpl не подходит для «указателя на реализацию» и предлагает удобный способ скрыть реализации в классах. Я реализации оконного класса, который скрывает от платформы функций и структур от пользователей данного класса, и поэтому интерфейс класса заканчивает тем, что довольно чистый:Может ли класс с pimpl использовать объект с помощью pimpl?
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;
Это/OpenGL Графический контекст Direct3D (пользователь "ContextGraphics" может определить, что) и как вы мог бы догадаться, он использует Pimpl-идиомы, а также:
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);
};
проблема я столкнулся это компилятор:
Компилятор, похоже, не находит реализацию класса «ContextGraphics :: Helper», что ставит вопрос только в том случае, если класс с pimpl может использовать объект с pimpl вообще. Можно ли обойтись без размещения всех реализаций в исходном файле класса Window? Для меня это не кажется разумным решением.
У вас есть обычная проблема циклической зависимости. На этом сайте есть много информации об этом. Пимпл не имеет к этому никакого отношения. – Mat
@Mat: О, хорошо, чтобы иметь имя для этой проблемы. Благодаря! Это помогает найти возможное решение, если оно существует. – Helixirr
Ну, вопрос все еще остается - это возможно, и если да, то как? – Helixirr