PImpl 习语在单独的源文件中使用 std::unique_pointer 和实现 class
PImpl idiom using std::unique_pointer with the implementation class in a seperate source file
我正在编写一个简单的库来处理 window 跨不同平台的创建。为了抽象出特定于平台的代码,我想使用带有 std::unique_ptr 的 PImpl 惯用法,并提供具有工厂函数的特定于平台的私有实现。这是我目前拥有的:
Window.h:
#pragma once
#include <memory>
class Window
{
public:
Window();
~Window();
private:
class WindowImpl;
std::unique_ptr<WindowImpl> impl;
};
Window.cpp:
#include "Window.h"
#include "WindowImpl.h"
Window::Window() : impl(WindowImpl::create()) {}
Window::~Window() = default;
WindowImpl.h:
#include "Window.h"
#include <memory>
class Window::WindowImpl
{
public:
static std::unique_ptr<WindowImpl> create();
};
WindowImpl.cpp:
#include "WindowImpl.h"
std::unique_ptr<Window::WindowImpl> Window::WindowImpl::create()
{
// the plan is to return the platform specific WindowImpl implementation here
return std::make_unique<Window::WindowImpl>();
}
这似乎符合我的要求。我的问题是我目前必须在 WindowImpl.cpp 中的基本所有内容前面指定“Window::”。由于 Window 是 class 而不是命名空间 "using Window" 不起作用。我找到的有关此主题的示例在使用它的 class 的源文件中都有完整的 Impl class 定义,因此没有这个问题。但是如果我想从中导出特定于平台的实现,我需要在单独的 header 中使用 WindowImpl。
有没有办法将 WindowImpl 保留在它自己的 header/source 文件中并摆脱冗长的内容?
您可以使用类型别名,但是,这将需要您进行嵌套 class public,这可能会破坏 PImpl 习惯用法的使用:
using WImpl = typename Window::WindowImpl;
std::unique_ptr<WImpl> WImpl::create(){
//implementation goes here
}
编辑:
除此之外,您可能必须使用宏来消除冗长:
#define WIMPL Window::WindowImpl;
std::unique_ptr<WIMPL> WIMPL::create(){
//implementation goes here
}
我正在编写一个简单的库来处理 window 跨不同平台的创建。为了抽象出特定于平台的代码,我想使用带有 std::unique_ptr 的 PImpl 惯用法,并提供具有工厂函数的特定于平台的私有实现。这是我目前拥有的:
Window.h:
#pragma once
#include <memory>
class Window
{
public:
Window();
~Window();
private:
class WindowImpl;
std::unique_ptr<WindowImpl> impl;
};
Window.cpp:
#include "Window.h"
#include "WindowImpl.h"
Window::Window() : impl(WindowImpl::create()) {}
Window::~Window() = default;
WindowImpl.h:
#include "Window.h"
#include <memory>
class Window::WindowImpl
{
public:
static std::unique_ptr<WindowImpl> create();
};
WindowImpl.cpp:
#include "WindowImpl.h"
std::unique_ptr<Window::WindowImpl> Window::WindowImpl::create()
{
// the plan is to return the platform specific WindowImpl implementation here
return std::make_unique<Window::WindowImpl>();
}
这似乎符合我的要求。我的问题是我目前必须在 WindowImpl.cpp 中的基本所有内容前面指定“Window::”。由于 Window 是 class 而不是命名空间 "using Window" 不起作用。我找到的有关此主题的示例在使用它的 class 的源文件中都有完整的 Impl class 定义,因此没有这个问题。但是如果我想从中导出特定于平台的实现,我需要在单独的 header 中使用 WindowImpl。
有没有办法将 WindowImpl 保留在它自己的 header/source 文件中并摆脱冗长的内容?
您可以使用类型别名,但是,这将需要您进行嵌套 class public,这可能会破坏 PImpl 习惯用法的使用:
using WImpl = typename Window::WindowImpl;
std::unique_ptr<WImpl> WImpl::create(){
//implementation goes here
}
编辑:
除此之外,您可能必须使用宏来消除冗长:
#define WIMPL Window::WindowImpl;
std::unique_ptr<WIMPL> WIMPL::create(){
//implementation goes here
}