В С++ нет так называемых виртуальных конструкторов что дельфисты расценивают как большой не достаток. Но сложно ли их реализовить? НЕТ!
Пример
Unit1.h
#pragma once
#include "meta.h"
struct Base
{
virtual void Hello()=0;
Base()
{
std::cout<<"Base ctor"<<std::endl;
}
virtual ~Base()
{
std::cout<<"Base dtor"<<std::endl;
}
};
void DoSome(Meta<Base> meta);
Unit1.cpp
#include "stdafx.h"
#include "Unit1.h"
void DoSome(Meta<Base> meta)
{
scoped_meta_ptr<Base> ptr1(meta);//Создает обьект класса переданого в качестве параметра.
//реализована концепция не разделимого владения
shared_meta_ptr<Base> ptr2(meta);//Тоже создает обьект но реализован подсчет ссылок.
}
Unit2.cpp
#include "stdafx.h"
#include "Unit1.h"
struct Derived:Base
{
void Hello()
{
std::cout<<"Derived Hello"<<std::endl;
}
Derived()
{
std::cout<<"Derived ctor"<<std::endl;
}
~Derived()
{
std::cout<<"Derived dtor"<<std::endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
DoSome(Meta<Derived>());
return 0;
}
Не проверял но по идее должно работать и через границу длл.
А это сам код. Нуждается в доработке но это вполне рабочий прототип.
#pragma once
template<class T>
struct scoped_meta_ptr;
template<class T>
struct shared_meta_ptr;
template<class T>
struct Meta
{
friend struct scoped_meta_ptr;
friend struct shared_meta_ptr;
Meta(){}
template<class U>
Meta(const Meta<U>&)
{
creator=&Create<U>;
destroyer=&Destroy;
}
private:
typedef T*(*Creator)();
Creator creator;
typedef void(*Destroyer)(T*);
Destroyer destroyer;
template<class U>
static T* Create()
{
return new U;
}
static void Destroy(T* ptr)
{
delete ptr;
}
};
template<class T>
struct scoped_meta_ptr
{
friend struct shared_meta_ptr;
explicit scoped_meta_ptr(Meta<T> meta)
:meta_(meta)
,ptr_(meta_.creator())
{
}
scoped_meta_ptr(scoped_meta_ptr& that)
:meta_(that.meta_)
,ptr_(that.ptr_)
{
that.ptr_=0;
}
scoped_meta_ptr& operator=(scoped_meta_ptr& that)
{
if(this==&that)return *this;
meta_.destroyer(ptr_);
meta_=that.meta_;
ptr_=that.ptr_;
that.ptr_=0;
return *this;
}
~scoped_meta_ptr()
{
meta_.destroyer(ptr_);
}
T* operator ->()
{
return ptr_;
}
operator bool() const
{
return ptr_?true:false;
}
private:
Meta<T> meta_;
T* ptr_;
};
template<class T>
struct shared_meta_ptr
{
explicit shared_meta_ptr(Meta<T> meta)
:meta_(meta)
,ptr_(meta_.creator())
,count_(new int(1))
{
}
shared_meta_ptr(const shared_meta_ptr& that)
:meta_(that.meta_)
,ptr_(that.ptr_)
,count_(that.count_)
{
++(*count_);
}
shared_meta_ptr& operator=(const shared_meta_ptr& that)
{
if(this==&that)return *this;
Free();
meta_=that.meta_;
ptr_=that.ptr_;
count_=that.count_;
++(*count_);
return *this;
}
shared_meta_ptr(scoped_meta_ptr<T>& that)
:meta_(that.meta_)
,ptr_(that.ptr_)
,count_(new int(1))
{
that.ptr_=0;
}
shared_meta_ptr& operator=(scoped_meta_ptr<T>& that)
{
Free();
meta_=that.meta_;
ptr_=that.ptr_;
count_=new int(1);
that.ptr_=0;
return *this;
}
~shared_meta_ptr()
{
Free();
}
T* operator ->()
{
return ptr_;
}
operator bool() const
{
return ptr_?true:false;
}
bool operator==(const shared_meta_ptr& that)
{
return ptr_==that.ptr_;
}
bool operator!=(const shared_meta_ptr& that)
{
return ptr_!=that.ptr_;
}
private:
void Free()
{
if(!--(*count_))
{
delete count_;
meta_.destroyer(ptr_);
}
}
Meta<T> meta_;
T* ptr_;
int* count_;
};
... << RSDN@Home 1.0 beta 6a >>