C++ C++;两阶段初始化
我正在编写一个使用两阶段初始化的程序。它位于本机GUI API(目前为Win32)之上,并向用户隐藏其复杂性C++ C++;两阶段初始化,c++,initialization,unique-ptr,C++,Initialization,Unique Ptr,我正在编写一个使用两阶段初始化的程序。它位于本机GUI API(目前为Win32)之上,并向用户隐藏其复杂性 Windows对C++类的映射通常需要两个阶段的初始化:第一个阶段创建C++对象,第二个阶段创建API对象。 这是必需的,因为订阅窗口事件的第一个机会是在构造函数内部。因此,若您的基本构造函数在订阅事件之前已经创建了窗口,那个么您将错过一些。除此之外,不应该从C++中的构造函数调用虚拟函数,所以它没有办法。 我希望使用以下模式来确保Windows资源(窗口、GDI句柄等)的两阶段初始化
Windows对C++类的映射通常需要两个阶段的初始化:第一个阶段创建C++对象,第二个阶段创建API对象。 这是必需的,因为订阅窗口事件的第一个机会是在构造函数内部。因此,若您的基本构造函数在订阅事件之前已经创建了窗口,那个么您将错过一些。除此之外,不应该从C++中的构造函数调用虚拟函数,所以它没有办法。 我希望使用以下模式来确保Windows资源(窗口、GDI句柄等)的两阶段初始化:
所有使用资源的函数都有create()和destroy()成员函数,它们派生自基模板类template <class T>
class resource {
public:
virtual T* create()=0;
virtual void destroy()=0;
}
模板
类资源{
公众:
虚拟T*create()=0;
虚空销毁()=0;
}
然后,我可以由此派生类:
class wnd : resource<wnd> {
// do the magic
}
class-wnd:resource{
//施展魔法
}
要创建这些类,我想创建一个全局库函数,它可以执行以下操作:
template <class T, typename... A>
// TODO: Need a concept here, but not available yet.
static std::unique_ptr<T> create(A... args)
{
T* ptr = new T(args...);
ptr->create();
return std::unique_ptr<T>(ptr);
}
模板
//TODO:这里需要一个概念,但还不可用。
静态std::unique_ptr create(A…args)
{
T*ptr=新的T(参数…);
ptr->create();
返回std::unique_ptr(ptr);
}
因此,我会像auto-button=::create(ctor-args)
那样调用它,它会依次将参数传递给ctor,将unique_ptr返回给我的按钮,并对其调用create函数
现在我也想实施破坏。它将作为自定义删除程序附加到unique_ptr,并将调用destroy()。这就是我——理论上——认为它应该起作用的方式
// --- two phase construction pattern ---
template <typename T>
struct destroy {
void operator()(T* p) { p->destroy(); delete p; }
};
template <class T, typename... A>
static std::unique_ptr<T> create(A... args)
{
T* ptr = new T(args...);
ptr->create();
return std::unique_ptr<T, destroy<T>>(ptr);
}
/---两阶段施工模式---
模板
结构破坏{
void操作符()(T*p){p->destroy();delete p;}
};
模板
静态std::unique_ptr create(A…args)
{
T*ptr=新的T(参数…);
ptr->create();
返回std::unique_ptr(ptr);
}
问题是,这会失败,因为std::unique\u ptr不能转换为std::unique\u ptr您可以编写一个“holder”类,负责创建对象、初始化对象、完成对象并销毁对象
#include <iostream>
#include <memory>
template<class base>
class holder {
public:
template<class T, class... Args>
static holder createAndInitialize(Args... args) {
holder h = create<T, Args...>(args...);
h.initialize();
return h;
}
// to create but not initialize
template<class T, class... Args>
static holder create(Args... args) {
return holder(new T(args...));
}
void initialize() {
if (!m_initialized)
{
mres->initialize();
m_initialized = true;
}
}
void finalize()
{
if (m_initialized) {
mres->finalize();
m_initialized = false;
}
}
// access to the underlying pointer
const base *ptr() const {
return mres.get();
}
base *ptr() {
return mres.get();
}
~holder() {
finalize();
std::cout << "holder destructor" << std::endl;
}
private:
holder(base * res)
: mres(res), m_initialized(false)
{ }
holder(holder &&rhs)
: mres(std::move(rhs.mres)),
m_initialized(rhs.m_initialized)
{ }
std::unique_ptr<base> mres;
bool m_initialized;
};
class resource {
private: // Make these private so that clients cannot invoke directly
virtual void initialize()=0;
virtual void finalize()=0;
public:
virtual ~resource() {}
virtual void doSomething()=0;
friend class holder<resource>;
};
class wnd : public resource {
public:
void initialize() override {
std::cout << "in wnd " << mv << " initialize" << std::endl;
}
void finalize() override {
std::cout << "in wnd " << mv << " finalize" << std::endl;
}
void doSomething() override {
std::cout << "in wnd " << mv << " doSomething" << std::endl;
}
~wnd() {
std::cout << "in wnd " << mv << " destructor" << std::endl;
}
private:
wnd(int v)// make constructor private
: mv(v)
{
std::cout << "in wnd " << v << " constructor" << std::endl;
}
friend class holder<resource>; // add holder as friend
int mv;
};
// class which has some child resources
class wnd2 : public resource {
public:
// initialize the child objects
void initialize() override {
std::cout << "in wnd2 initialize" << std::endl;
mres1.initialize();
mres2.initialize();
}
// finalize the child objects
void finalize() override {
mres1.finalize();
mres2.finalize();
std::cout << "in wnd2 finalize" << std::endl;
}
void doSomething() override {
std::cout << "in wnd2 doSomething" << std::endl;
}
~wnd2() {
std::cout << "wnd2 destructor" << std::endl;
}
private:
// In the constructor, the child objects are only created and not initialized
wnd2()
: mres1(holder<resource>::create<wnd>(1)),
mres2(holder<resource>::create<wnd>(2))
{ }
holder<resource> mres1;
holder<resource> mres2;
friend class holder<resource>; // add holder as friend
};
int main()
{
holder<resource> h2 = holder<resource>::createAndInitialize<wnd2>();
h2.ptr()->doSomething();
}
#包括
#包括
模板
阶级持有者{
公众:
模板
静态保持架创建和初始化(Args…Args){
保持器h=创建(参数…);
h、 初始化();
返回h;
}
//创建但不初始化
模板
静态保持架创建(Args…Args){
报税表持有人(新T(参数…);
}
void initialize(){
如果(!m_已初始化)
{
mres->initialize();
m_initialized=true;
}
}
void finalize()
{
如果(m_已初始化){
mres->finalize();
m_initialized=false;
}
}
//对底层指针的访问
常数基*ptr()常数{
返回mres.get();
}
基本*ptr(){
返回mres.get();
}
~holder(){
定稿();
标准::cout