Кто сказал что в С++ нет виртуальных конструкторов?
От: 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) А. Эйнштейн
Re: Кто сказал что в С++ нет виртуальных конструкторов?
От: ZORK Россия www.zorkaltsev.com
Дата: 05.06.03 02:57
Оценка: +1
Здравствуйте, WolfHound, Вы писали:

WH>В С++ нет так называемых виртуальных конструкторов что дельфисты расценивают как большой не достаток. Но сложно ли их реализовить? НЕТ!


А можно, please, определение виртуального контруктора, а то както не понятно о чем речь

-zork
Думать надо ...головой :)
Re: Кто сказал что в С++ нет виртуальных конструкторов?
От: main  
Дата: 05.06.03 03:25
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>В С++ нет так называемых виртуальных конструкторов что дельфисты расценивают как большой не достаток. Но сложно ли их реализовить? НЕТ!

WH>[/ccode]

О чем спор, в дельфях вообще НЕТ конструкторов
Re: Кто сказал что в С++ нет виртуальных конструкторов?
От: ArtDenis Россия  
Дата: 05.06.03 04:18
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>В С++ нет так называемых виртуальных конструкторов что дельфисты расценивают как большой не достаток. Но сложно ли их реализовить? НЕТ!

WH>Пример
WH>

Ну ты и загнул... Хотя после небольшой переделки всё это работает.

Для реализации виртуального конструктора вполне достаточно (IMHO):
1. Иметь базовую виртуальную функцию для создания экземпляра класса
2. Иметь указатель на функцию создания экземпляра и инициализировать её в конструкторе наследника. Этот вариант легко и удобно реализуется при помощи шаблонов.

Кроме того, для реализации ссылки на тип, на мой взгляд, действительного приемущества Virtual Pscal'я, можно применять фабрику объектов. Я, например, использую шаблон фабрики написанной по "заветам Александреску"

Денис.
... << RSDN@Home 1.0 beta 7a >>
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[2]: Кто сказал что в С++ нет виртуальных конструкторов?
От: WolfHound  
Дата: 05.06.03 05:04
Оценка:
Здравствуйте, ZORK, Вы писали:

ZOR>А можно, please, определение виртуального контруктора, а то както не понятно о чем речь

Само название на мысли не наталкивает? Если нет то это механизм создания производных классов имея инвормацию только о базовом.
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: Кто сказал что в С++ нет виртуальных конструкторов?
От: WolfHound  
Дата: 05.06.03 05:06
Оценка:
Здравствуйте, ArtDenis, Вы писали:

AD>Для реализации виртуального конструктора вполне достаточно (IMHO):

AD>1. Иметь базовую виртуальную функцию для создания экземпляра класса
ЧАВО????
AD>2. Иметь указатель на функцию создания экземпляра и инициализировать её в конструкторе наследника. Этот вариант легко и удобно реализуется при помощи шаблонов.
А я что делаю? Только надо еще функцию удаления тк это механизм планируется использовать через границу длл.

AD>Кроме того, для реализации ссылки на тип, на мой взгляд, действительного приемущества Virtual Pscal'я, можно применять фабрику объектов. Я, например, использую шаблон фабрики написанной по "заветам Александреску"

А это чем не ссылка на тип?
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: Кто сказал что в С++ нет виртуальных конструкторов?
От: ZORK Россия www.zorkaltsev.com
Дата: 05.06.03 05:08
Оценка:
Здравствуйте, WolfHound, Вы писали:

ZOR>>А можно, please, определение виртуального контруктора, а то както не понятно о чем речь

WH>Само название на мысли не наталкивает? Если нет то это механизм создания производных классов имея инвормацию только о базовом.

Нет — не наталкивает , так как я привык думать что виртуальные методы определяются через vTable, которого очевидно нет, когда объект еще не создан. Но есть мнение, что за этим причудилвым названием ("виртуальный конструктор") скрывается Abstract Factory Design Pattern. Или я ошибаюсь?

-zork
Думать надо ...головой :)
Re[3]: Кто сказал что в С++ нет виртуальных конструкторов?
От: ArtDenis Россия  
Дата: 05.06.03 05:29
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, ArtDenis, Вы писали:


AD>>Для реализации виртуального конструктора вполне достаточно (IMHO):

AD>>1. Иметь базовую виртуальную функцию для создания экземпляра класса
WH>ЧАВО????

class BASE
{
  ...
  virtual BASE* create() = 0;
  ...
};

class DERIVED
{
  virtual BASE* create() { return new DERIVED; } 
};

И никаких извращений.

AD>>Кроме того, для реализации ссылки на тип, на мой взгляд, действительного приемущества Virtual Pscal'я, можно применять фабрику объектов. Я, например, использую шаблон фабрики написанной по "заветам Александреску"

WH>А это чем не ссылка на тип?

Ссылка на тип в паскале — это один из типов данных самого языка. Т.е. эта ссылка может передаватся в функцию, по этой ссылке могут вызыватся конструкторы и т.д. Фабрика объектов — это творение самого программиста. Максимум, что она умеет — это создавать или копировать объекты. В случае с фабрикой стоит проблема регистрации объектов, если фабрика находится в dll, кроме того при созданни большого количества объектов фабрика проигрывает ссылке на тип. Когда ты используешь ссылку на тип, тебя не волнует, будет ли создан объект в Dll или в exe-шнике, главное чтобы у них был один и тот-же менеджер памяти.

PS: Не стоит рассматривать моё сообщение, как наезд на C++. Сам пишу на C++
... << RSDN@Home 1.0 beta 7a >>
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[4]: Кто сказал что в С++ нет виртуальных конструкторов?
От: WolfHound  
Дата: 05.06.03 05:38
Оценка:
Здравствуйте, ArtDenis, Вы писали:

AD>И никаких извращений.

Это работать не будет.

AD>Ссылка на тип в паскале — это один из типов данных самого языка. Т.е. эта ссылка может передаватся в функцию, по этой ссылке могут вызыватся конструкторы и т.д. Фабрика объектов — это творение самого программиста. Максимум, что она умеет — это создавать или копировать объекты. В случае с фабрикой стоит проблема регистрации объектов, если фабрика находится в dll, кроме того при созданни большого количества объектов фабрика проигрывает ссылке на тип. Когда ты используешь ссылку на тип, тебя не волнует, будет ли создан объект в Dll или в exe-шнике, главное чтобы у них был один и тот-же менеджер памяти.

Еще раз медитируем над моим текстом и говорим чем это отличается от того что ты толькочто написал. Кроме того что мне безразлично один менеджер памяти или много.
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[4]: Кто сказал что в С++ нет виртуальных конструкторов?
От: WolfHound  
Дата: 05.06.03 05:43
Оценка:
Здравствуйте, ZORK, Вы писали:

ZOR>Нет — не наталкивает , так как я привык думать что виртуальные методы определяются через vTable, которого очевидно нет, когда объект еще не создан. Но есть мнение, что за этим причудилвым названием ("виртуальный конструктор") скрывается Abstract Factory Design Pattern. Или я ошибаюсь?

В общем да. ПРосто я стремился получить максимально близкую сенематику к дельфям.
Хотя если присмотрться то шаблом Meta фактически генератор виртуальной таблици.
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[5]: Кто сказал что в С++ нет виртуальных конструкторов?
От: ZORK Россия www.zorkaltsev.com
Дата: 05.06.03 05:49
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, ZORK, Вы писали:


ZOR>>Нет — не наталкивает , так как я привык думать что виртуальные методы определяются через vTable, которого очевидно нет, когда объект еще не создан. Но есть мнение, что за этим причудилвым названием ("виртуальный конструктор") скрывается Abstract Factory Design Pattern. Или я ошибаюсь?

WH>В общем да. ПРосто я стремился получить максимально близкую сенематику к дельфям.
WH>Хотя если присмотрться то шаблом Meta фактически генератор виртуальной таблици.

Понял!
Думать надо ...головой :)
Re[5]: Кто сказал что в С++ нет виртуальных конструкторов?
От: ArtDenis Россия  
Дата: 05.06.03 05:55
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, ArtDenis, Вы писали:


AD>>И никаких извращений.

WH>Это работать не будет.
Почему ?

AD>>Ссылка на тип в паскале — это один из типов данных самого языка. Т.е. эта ссылка может передаватся в функцию, по этой ссылке могут вызыватся конструкторы и т.д. Фабрика объектов — это творение самого программиста. Максимум, что она умеет — это создавать или копировать объекты. В случае с фабрикой стоит проблема регистрации объектов, если фабрика находится в dll, кроме того при созданни большого количества объектов фабрика проигрывает ссылке на тип. Когда ты используешь ссылку на тип, тебя не волнует, будет ли создан объект в Dll или в exe-шнике, главное чтобы у них был один и тот-же менеджер памяти.

WH>Еще раз медитируем над моим текстом и говорим чем это отличается от того что ты толькочто написал. Кроме того что мне безразлично один менеджер памяти или много.

Блин, точно! Вчера тестил (и правил) твой код ночью, поэтому основной идеи и не заметил . Хотя сам бы написал немножко по-другому.
... << RSDN@Home 1.0 beta 7a >>
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[6]: Кто сказал что в С++ нет виртуальных конструкторов?
От: WolfHound  
Дата: 05.06.03 16:35
Оценка:
Здравствуйте, ArtDenis, Вы писали:

AD>>>И никаких извращений.

WH>>Это работать не будет.
AD>Почему ?
Попробуй сотвори... Узнаешь много нового о С++ и виртуальных функциях в часности. Конкретно для того чтобы была вызвана виртуальная функция класса Derived нужно иметь экземпляр класса Derived.
... << RSDN@Home 1.0 beta 6a >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[7]: Кто сказал что в С++ нет виртуальных конструкторов?
От: ArtDenis Россия  
Дата: 05.06.03 17:17
Оценка:
Здравствуйте, WolfHound, Вы писали:
WH>>>Это работать не будет.
AD>>Почему ?
WH>Попробуй сотвори... Узнаешь много нового о С++ и виртуальных функциях в часности. Конкретно для того чтобы была вызвана виртуальная функция класса Derived нужно иметь экземпляр класса Derived.

Я имел ввиду, что это нужно для копирования объекта, если мы имеем только указатель на базовый класс.
... << RSDN@Home 1.0 beta 7a >>
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re: Кто сказал что в С++ нет виртуальных конструкторов?
От: WolfHound  
Дата: 06.06.03 11:49
Оценка:
Здравствуйте, WolfHound, Вы писали:

Я тут сотворил конвертацию типов те обьект можно привести к любому типу из иерархии.
Вот я думаю оставить как сейчас
    MetaPtr<Base> ptr0=meta.Create();
    MetaPtr<Base2> ptr2=ptr0.Convert<Base2>();

или сделать не явно
    MetaPtr<Base> ptr0=meta.Create();
    MetaPtr<Base2> ptr2=ptr0;

Как лучше?
Во втором проще совершить ошибку.
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: Кто сказал что в С++ нет виртуальных конструкторов?
От: WFrag США  
Дата: 06.06.03 12:21
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, WolfHound, Вы писали:


WH>Я тут сотворил конвертацию типов те обьект можно привести к любому типу из иерархии.

WH>Вот я думаю оставить как сейчас
WH>
WH>    MetaPtr<Base> ptr0=meta.Create();
WH>    MetaPtr<Base2> ptr2=ptr0.Convert<Base2>();
WH>

WH>или сделать не явно
WH>
WH>    MetaPtr<Base> ptr0=meta.Create();
WH>    MetaPtr<Base2> ptr2=ptr0;
WH>

WH>Как лучше?
WH>Во втором проще совершить ошибку.

Сделай с полиси, как завещал Александреску.
7. О чем невозможно говорить, о том следует молчать.
Re[3]: Кто сказал что в С++ нет виртуальных конструкторов?
От: WolfHound  
Дата: 06.06.03 13:43
Оценка:
Здравствуйте, WFrag, Вы писали:

WF>Сделай с полиси, как завещал Александреску.

А как полиси могут влиять на наличие/оттсутствие шаблонных конструкторов/операторов присваивания?
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[4]: Кто сказал что в С++ нет виртуальных конструкторов?
От: WFrag США  
Дата: 06.06.03 16:45
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, WFrag, Вы писали:


WF>>Сделай с полиси, как завещал Александреску.

WH>А как полиси могут влиять на наличие/оттсутствие шаблонных конструкторов/операторов присваивания?

Я не спец в этом вопросе, но по-моему в SmartPtr что-то похожее есть.

Далее — обрывки мыслей на тему, как можно влиять на наличие конструкторов/операторов присваивания (Для произвольного типа в правой части. Если нужно разрешать/запрещать, когда справа только MetaPtr, то все проще), причем если преобразование запрещено, то компилятор говорит, что преобразования нет (в SmartPtr, вроде бы, выдается, например, что нельзя одно полиси в другое преобразовать):

I. Первая идея:

Сделать базовую реализацию.

class MetaPtrBase<...>
{
    // ...
};


Далее делаем так:

template <bool allow>
class MetaPtr;

template<>
class MetaPtr<true> : public MetaPtrBase
{
    // Здесь придется написать все конструкторы,
    // плюс те, которые разрешаются данной полиси==true
    // (в данном случае роль полиси играет flag)
};

template<>
class MetaPtr<false> : public MetaPtrBase
{
    // Здесь нужно придется все конструкторы,
    // кроме тех, которые запрещаются данной полиси==false
    // (в данном случае роль полиси играет flag)
};


В случае с операторами присваивания попроще будет, они наследуются.

II. Второй вариант:

Можно попробовать поиграться с Loki::Select, выбирая либо нормальный тип параметра конструктора, либо фиктивный. При этом придется делегировать конструирование некой функции. Что-то вроде:

template<bool allow>
class MetaPtr
{
template<bool allow>
class Test
{
private:
    class Dummy
    {
    };
public:
    Test( typename Loki::Select<allow, /*Нужный тип параметра*/, Dummy>::Result param )
    {
        _construct( param );
    }
private:
    void _construct( /*Нужный тип параметра*/ param )
    {
        // нужные действия
    }

    void _construct( Dummy param )
    {
    }
}


Первый вариант плох тем, что при увеличении количества всяких полиси подобного типа возможен комбинаторный взрыв специализаций классов MetaPtr (собирать набор конструкторов из разных классов нельзя — они не наследуются, а другого варианта я не вижу).

А второй вариант, похоже, не прокатывает для шаблонных конструкторов (которые, собственно, и нужны) .


Можно, конечно, просто статический ассерт вставить, но это некрасиво. Лучше, когда компилятор явно скажет, что такого преобразования/конструктора нет.

Вот такие вот мысли.
7. О чем невозможно говорить, о том следует молчать.
Re: Кто сказал что в С++ нет виртуальных конструкторов?
От: Alexey Shirshov Россия http://wise-orm.com
Дата: 08.06.03 10:16
Оценка: 12 (2) +1
Здравствуйте, WolfHound, Вы писали:

Опять извращение.
У меня оно даже не скомпилялось (VS 7.0)

И чем это отличается от
using std::cout;
using std::endl;

class Base
{
public:
    virtual void Hello() const
    {
        cout << "Base: Hello!" << endl;
    }
};

class Derived : public Base
{
public:
    void Hello() const
    {
        cout << "Derived: Hello!" << endl;
    }
};

class SomeOther
{
};

template<class T>
Base* CreateCLS(void)
{
    return new T();
}

int _tmain()
{
    std::auto_ptr<Base> c(CreateCLS<Derived>());
    c->Hello();
    
    //error
    //std::auto_ptr<Base> c(CreateCLS<SomeOther>());
    return 0;
}


ИМХО, ты не достаточно четко представляешь себе этот паттерн. Его идея очень проста: не прошивать в коде создание конкретных классов. Созданием объектов должно быть сгруппировано в одном месте для того, чтобы не приходилось вносить большое кол-во изменений в код. Например
class Saver
{
public:
    virtual void Save(void) = 0;
};

Saver* CreateSaver(bool fToDisk = true);

class SaverToDisk : public Saver
{
    friend Saver* CreateSaver(bool fToDisk);
protected:
    SaverToDisk(){}
private:
    void Save(void)
    {
        cout << "save to disk" << endl;
    }
};

class SaverToPipe : public Saver
{
    friend Saver* CreateSaver(bool fToDisk);
protected:
    SaverToPipe(){}
private:
    void Save(void)
    {
        cout << "save to pipe" << endl;
    }
};

Saver* CreateSaver(bool fToDisk = true)
{
    if (fToDisk)
        return new SaverToDisk();
    else
        return new SaverToPipe();
}

int _tmain()
{
    std::auto_ptr<Saver> s(CreateSaver(false));
    s->Save();
    return 0;
}


В программе используется интерфейс Saver, а создание происходит только в одном месте. Можно убрать параметр и захардкодить конктерный объект в CreateSaver.
Еще заметь, реализация методов закрыта (private), а конструкторы защищены. Нужно это для того, чтобы клиент не мог создать классы реализации даже если чего-то про них пронюхает.
Все это хозяйство выноситься в отдельный модуль и наступает счастье.
Re[2]: Кто сказал что в С++ нет виртуальных конструкторов?
От: WolfHound  
Дата: 08.06.03 20:27
Оценка:
Здравствуйте, Alexey Shirshov, Вы писали:

AS>Опять извращение.

Опять не разобравшись критикуешь.
AS>У меня оно даже не скомпилялось (VS 7.0)
А я разве обещал? Скоро выложу значительно доработаную версию с конвертацией типов и клонированием.
AS>И чем это отличается от
Тем что DoSome может лежать в другой длл. Плюс я могу накидать еще длл которые будут содержать другие реализации причем длл с DoSome не надо перекомпилировать.

AS>ИМХО, ты не достаточно четко представляешь себе этот паттерн.

Вот не надо что такое фабрика классов я знаю очень хорошо. Тут ставилась немного другая задача.

AS>В программе используется интерфейс Saver, а создание происходит только в одном месте.

А я могу создавать где угодно и какие угодно причем без ПЕРЕКОМПИЛЯЦИИ что не моловажно когда колличество длл зашкаливает за 10.
AS>Еще заметь, реализация методов закрыта (private), а конструкторы защищены. Нужно это для того, чтобы клиент не мог создать классы реализации даже если чего-то про них пронюхает.
Ты меня за кого держишь?
AS>Все это хозяйство выноситься в отдельный модуль и наступает счастье.
... << RSDN@Home 1.0 beta 6a >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: Кто сказал что в С++ нет виртуальных конструкторов?
От: Alexey Shirshov Россия http://wise-orm.com
Дата: 09.06.03 07:12
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, Alexey Shirshov, Вы писали:


AS>>Опять извращение.

WH>Опять не разобравшись критикуешь.

Почему не разобравшись?

AS>>У меня оно даже не скомпилялось (VS 7.0)

WH>А я разве обещал? Скоро выложу значительно доработаную версию с конвертацией типов и клонированием.

А зачем изобретать вилосипед? Свои смарт-поинтеры писать...

AS>>И чем это отличается от

WH>Тем что DoSome может лежать в другой длл. Плюс я могу накидать еще длл которые будут содержать другие реализации причем длл с DoSome не надо перекомпилировать.

А зачем? Ты разделяй процесс конструирования объектов от их реализации. Я тоже могу понаписать кучу реализаций и конструировать с помощью той же CreateCLS. И запихать информацию о конструируемом типе тоже запросто могу. Я не понимаю, почему так сложно у тебя все получается?
Зачем, например Destroy вызывать косвено? Он никак не зависит от передаваемого тип (насколько я понял, это у тебя параметр U).

[]

WH>Вот не надо что такое фабрика классов я знаю очень хорошо. Тут ставилась немного другая задача.


Интересно какая.

хъ

WH>А я могу создавать где угодно и какие угодно причем без ПЕРЕКОМПИЛЯЦИИ что не моловажно когда колличество длл зашкаливает за 10.


Перекомпиляции чего?

хъ

WH>Ты меня за кого держишь?


Если бы твой код был бы настолько простым, насколько он сейчас сложен (при одинаковых результатах и без потери в функциональности и производительности) — цены бы тебе не было.

Тебе должен быть известен факт того, что на сях можно писать очень запутанный код, однако истинная ценность в простом и понятном коде.
Re[4]: Кто сказал что в С++ нет виртуальных конструкторов?
От: WolfHound  
Дата: 09.06.03 16:57
Оценка:
Здравствуйте, Alexey Shirshov, Вы писали:

AS>А зачем? Ты разделяй процесс конструирования объектов от их реализации. Я тоже могу понаписать кучу реализаций и конструировать с помощью той же CreateCLS. И запихать информацию о конструируемом типе тоже запросто могу. Я не понимаю, почему так сложно у тебя все получается?

Я действую по ринципу
Пусть это будет просто: 
просто, как только можно, 
но не проще. 
(C) А. Эйнштейн

А ты хочешь проще чем можно.
AS>Зачем, например Destroy вызывать косвено? Он никак не зависит от передаваемого тип (насколько я понял, это у тебя параметр U).
А за тем что это должно работать через границу dll. Надеюсь не надо обьяснять что в каждой dll СВОЙ менеджер памяти а то и не один. И надеюсь ты понимаешь что произойдет если память выделеную одним отдать другому, а именно это и случится при прямом вызове Destroy или delete.

AS>Если бы твой код был бы настолько простым, насколько он сейчас сложен (при одинаковых результатах и без потери в функциональности и производительности) — цены бы тебе не было.

Пусть это будет просто: 
просто, как только можно, 
но не проще. 
(C) А. Эйнштейн

AS>Тебе должен быть известен факт того, что на сях можно писать очень запутанный код, однако истинная ценность в простом и понятном коде.
А ты знаешь как ИМЕННО работает stl, boost, Loki...? А ведь это тоже библиотека причем с очень простым интерфейсом и хорошей защитой от дурака.

ЗЫ Вышла новая версия Виртуальные конструкторы 2
Автор: WolfHound
Дата: 09.06.03
... << RSDN@Home 1.0 beta 6a >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[5]: Кто сказал что в С++ нет виртуальных конструкторов?
От: Alexey Shirshov Россия http://wise-orm.com
Дата: 10.06.03 04:22
Оценка:
Здравствуйте, WolfHound, Вы писали:

[]

WH>А за тем что это должно работать через границу dll. Надеюсь не надо обьяснять что в каждой dll СВОЙ менеджер памяти а то и не один. И надеюсь ты понимаешь что произойдет если память выделеную одним отдать другому, а именно это и случится при прямом вызове Destroy или delete.


Каким образом метод вызова функции (косвеный или прямой) может повлиять на поведение ее кода?

хъ

WH>А ты знаешь как ИМЕННО работает stl, boost, Loki...? А ведь это тоже библиотека причем с очень простым интерфейсом и хорошей защитой от дурака.


Нет. А что?
Вся вишка в том, что проще писать сложный код. Для того чтобы написать простой код, нужно действительно сеть и подумать. Над архитектурой, интерфейсами, вообще назначением кода. Все гениальное — просто.
Re[6]: Кто сказал что в С++ нет виртуальных конструкторов?
От: WolfHound  
Дата: 10.06.03 04:47
Оценка:
Здравствуйте, Alexey Shirshov, Вы писали:

AS>Каким образом метод вызова функции (косвеный или прямой) может повлиять на поведение ее кода?

Элементарно ибо будут вызваны РАЗНЫЕ функции. При явном вызове из другой длл будет сгенерирована и вызвана функция из другой длл, а при косвенном будет вызвана функция из правильной длл те из тойже что и Create<U>.

AS>Вся вишка в том, что проще писать сложный код. Для того чтобы написать простой код, нужно действительно сеть и подумать. Над архитектурой, интерфейсами, вообще назначением кода. Все гениальное — просто.

Вся фишка в том что проще не напишешь.
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[7]: Кто сказал что в С++ нет виртуальных конструкторов?
От: Alexey Shirshov Россия http://wise-orm.com
Дата: 10.06.03 05:48
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, Alexey Shirshov, Вы писали:


AS>>Каким образом метод вызова функции (косвеный или прямой) может повлиять на поведение ее кода?

WH>Элементарно ибо будут вызваны РАЗНЫЕ функции. При явном вызове из другой длл будет сгенерирована и вызвана функция из другой длл, а при косвенном будет вызвана функция из правильной длл те из тойже что и Create<U>.

Что-то ты совсем запутался. У тебя создание у уничтожение объекта проиходит в одной функции — DoSome. В какой длл она лежит в контексте такой и будет происходить создание и разрушение объекта. Это раз.
Во вторых, в какой длл Meta инстанциировался в той и будет вызван Destroy (и Create). Совершено не зависит от того косвено он будет вызван или нет. Похоже ты не понимаешь просто, что не нужно делать его статическим, так как в своих смарт поинтерах ты все-равно держишь ссылку на реальный объект Meta.
Re[2]: Кто сказал что в С++ нет виртуальных конструкторов?
От: Hacker_Delphi Россия  
Дата: 10.06.03 09:11
Оценка:
Здравствуйте, main, Вы писали:

M>О чем спор, в дельфях вообще НЕТ конструкторов

ЧАВО?????
... << RSDN@Home 1.0 beta 7b >>
Если при компиляции и исполнении вашей программы не происходит ни одной ошибки — это ошибка компилятора :)))
Re[8]: Кто сказал что в С++ нет виртуальных конструкторов?
От: WolfHound  
Дата: 10.06.03 10:02
Оценка:
Здравствуйте, Alexey Shirshov, Вы писали:

AS>Что-то ты совсем запутался. У тебя создание у уничтожение объекта проиходит в одной функции — DoSome.

В общем случае время жизни обьекта неопределенно дольше чем время выполнения DoSome и он может быть разрушин в третьей длл.
AS>В какой длл она лежит в контексте такой и будет происходить создание и разрушение объекта. Это раз.
Ты давно с дллками работал?
AS>Во вторых, в какой длл Meta инстанциировался в той и будет вызван Destroy (и Create).
Именно этого я и добиваюсь.
AS>Совершено не зависит от того косвено он будет вызван или нет.
Проверь.
AS>Похоже ты не понимаешь просто, что не нужно делать его статическим, так как в своих смарт поинтерах ты все-равно держишь ссылку на реальный объект Meta.
Ну как вариант можно ее сделать виртуальной (именно так я и поступил с клонами) но если Meta будет скопирована то и это не поможет.
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[9]: Кто сказал что в С++ нет виртуальных конструкторов?
От: Alexey Shirshov Россия http://wise-orm.com
Дата: 10.06.03 13:14
Оценка:
Здравствуйте, WolfHound, Вы писали:

[]

WH>В общем случае время жизни обьекта неопределенно дольше чем время выполнения DoSome и он может быть разрушин в третьей длл.


В твоем случае это не так.

хъ

WH> Ты давно с дллками работал?


Давно.

хъ

WH>Ну как вариант можно ее сделать в1иртуальной (именно так я и поступил с клонами) но если Meta будет скопирована то и это не поможет.


Короче вот тебе вариант. Работает даже на шестерке. Пришлось кое-чего открыть так как VS 6.0 плохо дружит с друзьями-шаблонами.
class Base
{
public:
    virtual void Hello() const {}
};

template<class T>
struct scoped_meta_ptr;
template<class T>
struct shared_meta_ptr;
template<class T>
struct Meta
{
    template<class T1>
    struct cls_creator
    {
        virtual T* create()
        {
            return new T1;
        }

        virtual void destroy(T* t)
        {
            delete t;
        }
    };

//    friend struct scoped_meta_ptr;
//    friend struct shared_meta_ptr;
    Meta(){}

    template<class U>
    Meta(const Meta<U>&)
    {
        c = (cls_creator<T>*)new(buf) cls_creator<U>;
    }

    cls_creator<T>* c;
    char buf[100];
};

template<class T>
struct scoped_meta_ptr
{
    friend struct shared_meta_ptr;
    explicit scoped_meta_ptr(Meta<T> meta)
        :meta_(meta)
        ,ptr_(meta.c->create())
    {
    }
    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_.c->destroy(ptr_);
        meta_=that.meta_;
        ptr_=that.ptr_;
        that.ptr_=0;
        return *this;
    }
    ~scoped_meta_ptr()
    {
        meta_.c->destroy(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.c->create())
        ,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_.c->destroy(ptr_);
        }
    }
    Meta<T> meta_;
    T* ptr_;
    int* count_;
};


И скажи что это получилось сложнее? И никакой локи не нужен.
Re[10]: Кто сказал что в С++ нет виртуальных конструкторов?
От: WolfHound  
Дата: 10.06.03 16:24
Оценка:
Здравствуйте, Alexey Shirshov, Вы писали:

AS>В твоем случае это не так.

В моем случае это ТЕСТОВЫЙ пример.

AS>Короче вот тебе вариант. Работает даже на шестерке. Пришлось кое-чего открыть так как VS 6.0 плохо дружит с друзьями-шаблонами.

AS>
AS>class Base
AS>{
AS>public:
AS>    virtual void Hello() const {}
AS>};//А виртуальный деструктор где?


К остальному коду я добавил
struct Base
{
    virtual void Hello()=0;
    virtual ~Base(){}
};
struct Derived
    :Base
{
    virtual void Hello(){std::cout<<"Hello\n";}
};
void DoSome(Meta<Base> cls)
{
    scoped_meta_ptr<Base> ptr(cls);
}
int main()
{
    DoSome(Meta<Derived>());
    return 0;
}

И вот что по этому поводу думает VC++7.1
------ Build started: Project: ___, Configuration: Release Win32 ------

Compiling...
___.cpp
___.cpp(20) : error C2259: 'Base' : cannot instantiate abstract class
        due to following members:
        'void Base::Hello(void)' : pure virtual function was not defined
        ___.cpp(163) : see declaration of 'Base::Hello'
        ___.cpp(19) : while compiling class-template member function 'Base *Meta<T>::cls_creator<T1>::create(void)'
        with
        [
            T=Base,
            T1=Base
        ]
        ___.cpp(49) : see reference to class template instantiation 'Meta<T>::cls_creator<T1>' being compiled
        with
        [
            T=Base,
            T1=Base
        ]
        ___.cpp(47) : while compiling class-template member function 'scoped_meta_ptr<T>::scoped_meta_ptr(Meta<T>)'
        with
        [
            T=Base
        ]
        ___.cpp(173) : see reference to class template instantiation 'scoped_meta_ptr<T>' being compiled
        with
        [
            T=Base
        ]


AS>И скажи что это получилось сложнее? И никакой локи не нужен.

Получилось почти также это раз.
Получилось не правильно это два.
Loki использован во второй ЗНАЧИТЕЛЬНО расширеной версии это три.

ЗЫ "Злой каст" это не хорошо интересно что произойдет при множественном наследовании? А виртуальном?
    template<class U>
    Meta(const Meta<U>&)
    {
        c = (cls_creator<T>*)new(buf) cls_creator<U>;
    }
... << RSDN@Home 1.0 beta 6a >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[11]: Кто сказал что в С++ нет виртуальных конструкторов?
От: Alexey Shirshov Россия http://wise-orm.com
Дата: 11.06.03 07:18
Оценка:
Здравствуйте, WolfHound, Вы писали:

[]

WH>И вот что по этому поводу думает VC++7.1

WH>
[]
WH>


Hellow не должна быть абстрактной.

хъ

WH>Получилось почти также это раз.


Это компилиться даже на шестерке.

WH>Получилось не правильно это два.


Это почему?

хъ

WH>ЗЫ "Злой каст" это не хорошо интересно что произойдет при множественном наследовании? А виртуальном?


хъ

Не хороша твоя архитектура, где нужно таким способом извращаться.
Даже не понятно какой паттерн ты реализуешь и чего вообще хочешь. Если просто побаловаться, тогда все понятно.
Re[12]: Кто сказал что в С++ нет виртуальных конструкторов?
От: WolfHound  
Дата: 11.06.03 15:01
Оценка:
Здравствуйте, Alexey Shirshov, Вы писали:

AS>Hellow не должна быть абстрактной.



WH>>Получилось почти также это раз.

AS>Это компилиться даже на шестерке.
И что? Я уже семерку выкинул.
WH>>Получилось не правильно это два.
AS>Это почему?
Не поддерживает абстрактные классы, наверняка грохнится на множественном и вартуальном наследовании...

AS>Не хороша твоя архитектура, где нужно таким способом извращаться.

Да причем тут архитектура? Не путай мух с катлетами.
AS>Даже не понятно какой паттерн ты реализуешь и чего вообще хочешь. Если просто побаловаться, тогда все понятно.
Что-то типа абстрактной фабрики классов.

Короче сначала напиши ПРАВИЛЬНО, с ТОЙЖЕ ФУНКЦИОНАЛЬНОСТЬТЮ и ПРОЩЕ вот тогда будет о чем разговаривать, а пока это не обаснованый наезд с твоей стороны.
... << RSDN@Home 1.0 beta 6a >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: Кто сказал что в С++ нет виртуальных конструкторов?
От: MaximE Великобритания  
Дата: 11.06.03 20:25
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>В С++ нет так называемых виртуальных конструкторов что дельфисты расценивают как большой не достаток. Но сложно ли их реализовить? НЕТ!


Паттерн виртуальный к-тор выгдядит так:

/**
 * @stereotype strategy 
 */
struct fetcher : ref_counted
{
    virtual eft_file_p fetch(server_id, seconds timeout) = 0;
};
typedef boost::intrusive_ptr<fetcher> fetcher_p;

fetcher_p fetcher_ctor(const profile_p&); // <- вот он, виртуальный к-тор


Вот это действительно просто.
Re[2]: Кто сказал что в С++ нет виртуальных конструкторов?
От: WolfHound  
Дата: 12.06.03 05:50
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Вот это действительно просто.

Там оч скудная документация
Напиши пример аналогичный этому
Автор: WolfHound
Дата: 09.06.03
, а я посмотрю.
... << RSDN@Home 1.0 beta 6a >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: Кто сказал что в С++ нет виртуальных конструкторов?
От: MaximE Великобритания  
Дата: 12.06.03 07:08
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, MaximE, Вы писали:


ME>>Вот это действительно просто.

WH>Там оч скудная документация

Какую док-цию ты имеешь в виду?

WH>Напиши пример аналогичный этому
Автор: WolfHound
Дата: 09.06.03
, а я посмотрю.


////////////////////////////////////////////////////////////////////////////////////////////////
// ref_counted.h

#pragma once

#include <boost/intrusive_ptr.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include <boost/static_assert.hpp>

////////////////////////////////////////////////////////////////////////////////////////////////

class ref_counted
{
public:
    virtual void add_ref() const = 0;
    virtual void release() const = 0;

protected:
    virtual ~ref_counted() {}
};

namespace boost // this functions must not hang in the global namespace
{

inline void intrusive_ptr_add_ref(ref_counted* p) { p->add_ref(); }
inline void intrusive_ptr_release(ref_counted* p) { p->release(); }

}

////////////////////////////////////////////////////////////////////////////////////////////////

template<class itf>
class ref_counted_impl : public itf
{
public: // ref_counted
    void add_ref() const { ++references_; }
    void release() const { if (!--references_) delete this; }

protected:
    ref_counted_impl()
        :    references_(0)
    {}

    ~ref_counted_impl()
    {
        BOOST_STATIC_ASSERT((boost::is_base_and_derived<ref_counted, itf>::value));
    }

private:
    mutable unsigned references_;
};

////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////
// hierarchy.h

#pragma once

#include "ref_counted.h"

////////////////////////////////////////////////////////////////////////////////////////////////

template<class T>
struct type_wrapper
{
    typedef T type;
};

////////////////////////////////////////////////////////////////////////////////////////////////

struct base : ref_counted
{
    virtual const char* who_are_you() const = 0;
    virtual base* clone() const = 0;
};
typedef boost::intrusive_ptr<base> base_p;

base_p virtual_ctor(type_wrapper<base>); // virtual constructor

////////////////////////////////////////////////////////////////////////////////////////////////

struct derived : base
{
    virtual derived* clone() const = 0;
};
typedef boost::intrusive_ptr<derived> derived_p;

derived_p virtual_ctor(type_wrapper<derived>); // virtual constructor

////////////////////////////////////////////////////////////////////////////////////////////////

template<class itf>
inline boost::intrusive_ptr<itf> virtual_ctor()  // virtual constructor / abstract factory
{
    return virtual_ctor(type_wrapper<itf>());
}

////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////
// hierarchy.cpp

#include "hierarchy.h"

////////////////////////////////////////////////////////////////////////////////////////////////

struct base_impl : ref_counted_impl<base>
{
    base* clone() const
    {
        return new base_impl(*this);
    }

    const char* who_are_you() const
    {
        return "I am base.";
    }
};

base_p virtual_ctor(type_wrapper<base>)
{
    return new base_impl;
}

////////////////////////////////////////////////////////////////////////////////////////////////

struct derived_impl : ref_counted_impl<derived>
{
    derived* clone() const
    {
        return new derived_impl(*this);
    }

    const char* who_are_you() const
    {
        return "I am derived.";
    }
};

derived_p virtual_ctor(type_wrapper<derived>)
{
    return new derived_impl;
}

////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////
// virtual_ctor.cpp : Defines the entry point for the console application.

#include <iostream>

#include "hierarchy.h"

////////////////////////////////////////////////////////////////////////////////////////////////

void f()
{
    using namespace std;

    base_p bb1(virtual_ctor<base>());
    base_p bd1(virtual_ctor<derived>());
    cout << bb1->who_are_you() << '\n';
    cout << bd1->who_are_you() << '\n';

    base_p bb2(bb1->clone());
    base_p bd2(bd1->clone());
    cout << bb2->who_are_you() << '\n';
    cout << bd2->who_are_you() << '\n';

    derived_p d1(static_cast<derived*>(bd2->clone()));
    cout << d1->who_are_you() << '\n';

    derived_p d2(d1->clone());
    cout << d2->who_are_you() << '\n';
};

////////////////////////////////////////////////////////////////////////////////////////////////

int main()
{
    f();
    return 0;
}

////////////////////////////////////////////////////////////////////////////////////////////////


Если бы hierarchy.cpp был бы в отдельной dll, то эта dll экспортировала бы лишь пару функций:

base_p virtual_ctor(type_wrapper<base>);
derived_p virtual_ctor(type_wrapper<derived>);
Re[4]: Кто сказал что в С++ нет виртуальных конструкторов?
От: WolfHound  
Дата: 12.06.03 15:18
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Какую док-цию ты имеешь в виду?

Та что с boost'ом

ME>Если бы hierarchy.cpp был бы в отдельной dll, то эта dll экспортировала бы лишь пару функций:

Ты не понял сути того что я сделал. Я полностью изолировал создание от реализации. В товоем примере ОБЕ длл должны по крайней мере знать описание derived, а в моей только base.
Следовательно при изменении описания derived я компилирую только одну длл, а ты ВСЕ связаные именно этого я и стремился избежать.
Да и как ты поступишь если одна длл которая знает описание Base должна прицепить произвольное колличество дллек с реализацией и создавать эти реализации?
Например при разработке АСУТП могут быть куча моделей какого либо устройства причем на логическом уровне они одинаковы, а на физическом ни чего общего. Соответственно при добавлении новых устройств в моей модели мы просто кидаем к уже лежащим ~100 дллкам еще одну и немного правим конфиг. Что придется делать с твоей моделью я даже представить боюсь.
... << RSDN@Home 1.0 beta 6a >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[5]: Кто сказал что в С++ нет виртуальных конструкторов?
От: MaximE Великобритания  
Дата: 12.06.03 16:31
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, MaximE, Вы писали:


WH>Например при разработке АСУТП могут быть куча моделей какого либо устройства причем на логическом уровне они одинаковы, а на физическом ни чего общего. Соответственно при добавлении новых устройств в моей модели мы просто кидаем к уже лежащим ~100 дллкам еще одну и немного правим конфиг. Что придется делать с твоей моделью я даже представить боюсь.


На этой модели я построил object-relational mapping framework. С помощью этого framework'a люди реализовали иерархии с более чем 500 классами и визжали от восторга / писали кипятком.

Это было сделано так. Была dll с фабрикой, на которую линковались dll с конкретными иерархиями и регистрировались в фабрике. У фабрики для удобства был похожий шаблонный factory method. Клиент цеплял dll'и c иерархиями с которыми он планировал работать (как угодно, хоть на этапе линковки, хоть в runtime). Каждая dll с иерархиями не экспортировала ни единой функции. В DllMain она регистрировала все свои объекты в фабрике.

Так что бояться не стоит
Re[13]: Кто сказал что в С++ нет виртуальных конструкторов?
От: Alexey Shirshov Россия http://wise-orm.com
Дата: 16.06.03 06:40
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, Alexey Shirshov, Вы писали:


[]

Вся твоя проблема заключается в управлении памятью. Вся остальное — твои извращения, которые к делу совершенно не относятся. Если бы передо мной стояла такая проблема я бы ее решил так:
class Base
{
public:
    virtual void Hello() const = 0;
    virtual ~Base(){}
    
    void* operator new(size_t nSize)
    {
        return HeapAlloc(GetProcessHeap(),0,nSize);
    }

    void operator delete(void* p)
    {
        HeapFree(GetProcessHeap(),0,p);
    }
};


И все. DoSome при этом превращается в
void DoSome(Base* b)
{
    std::auto_ptr<Base> p(b);
}

Никаких Meta и самодельных смарт поинтеров. Чем это тебе не нравиться?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.