Кто сказал что в С++ нет виртуальных конструкторов?
От: WolfHound  
Дата: 04.06.03 17:05
Оценка: 37 (4) -1
В С++ нет так называемых виртуальных конструкторов что дельфисты расценивают как большой не достаток. Но сложно ли их реализовить? НЕТ!
Пример
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 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.