Poprawa/optymalizacja klasy-multiType

0

Pomimo tego, że w c++ nie można zmieniać typu zmiennej chcę się zbliżyć do tego efektu.
Stworzyłem klasę o nazwie multiType która "zmienia swój typ" a raczej może przechowywać w sobie różne typy.
Całość wydaje się działać, to forma tego jest trochę dziwna. Czy mógłby ktoś sprawdzić kod i powiedzieć co można poprawić/dodać by od strony użytkownika wyglądało to lepiej? I czy można to zrobić bez dodatkowych bibliotek?

#ifndef MTYPE_H_INCLUDED
#define MTYPE_H_INCLUDED

#include <typeinfo>
#include <typeindex>
#include <map>

template<typename T>void deleter_func(void * source)
{
    T* target=(T*)source;
    delete target;
}

class multiType
{
    void * _storage;
    std::type_index typeGuard;
public:
    typedef void(*deleter)(void *);
    static std::map<std::type_index,deleter>delete_func;
    template<typename T>static void asign()
    {
        multiType::delete_func[std::type_index(typeid(T))]=deleter_func<T>;
    }
    template<typename T>T& value()
    {
        if (_storage!=NULL and std::type_index(typeid(T))==typeGuard)
            return *(T*)_storage;
        return *(new T);
    }
    template<typename T>void construct(T target=T())
    {
        if (_storage!=NULL)
        {
            if (delete_func.count(typeGuard)>0)
                delete_func[typeGuard](_storage);
        }
        typeGuard=typeid(T);
        _storage=new T(target);
    }
    template<typename B,typename T>void cast()
    {
        B*source=(B*)_storage;
        T*buffer=new T;
        *buffer=(T)(*source);
        delete source;
        _storage=buffer;
        typeGuard=typeid(T);
    }
    template<typename T>bool set(T target,bool respectType=true)
    {
        if (_storage==NULL or !respectType or std::type_index(typeid(T))==typeGuard)
        {
            if (delete_func.count(std::type_index(typeid(T)))==0)
            {
                asign<T>();
            }
            if (_storage==NULL)
            {
                _storage=new T;
            }
            else if (std::type_index(typeid(T))!=typeGuard)
            {
                if (delete_func.count(typeGuard)>0)
                    delete_func[typeGuard](_storage);
            }
            typeGuard=typeid(T);
            T* buffer=(T*)_storage;
            *buffer=target;
            return true;
        }
        return false;
    }
    multiType():typeGuard(typeid(NULL))
    {
        _storage=NULL;
    }
    template<typename T>multiType(T target):typeGuard(typeid(T))
    {
        _storage=new T;
        T*buffer=(T*)_storage;
        *buffer=target;
    }
    multiType(const multiType & target):typeGuard(target.typeGuard)
    {
        _storage=target._storage;
    }
    ~multiType()
    {
        if (_storage!=NULL and delete_func.count(typeGuard)>0)
            delete_func[typeGuard](_storage);
    }
};
std::map<std::type_index,multiType::deleter>multiType::delete_func;

#endif // MTYPE_H_INCLUDED
 
1

Czemu NULL, a nie nullptr?
Czemu castowanie z C?

Trochę nie rozumiem idei tego

template<typename T>void deleter_func(void * source)
{
    T* target=(T*)source;
    delete target;
}
  1. czemu jest poza klasą?
  2. Po co ona jest? Wszystko i tak usuwasz tak samo.

Po co w ogóle jest ta mapa funkcji usuwających? Nie, że źle czy coś. Pytam bo może nie rozumiem, a się przydaje.

To jest bardzo możliwy wyciek pamięci

template<typename T>T& value()
    {
        if (_storage!=NULL and std::type_index(typeid(T))==typeGuard)
            return *(T*)_storage;
        return *(new T);// o to
    }

Po co tu te new?

Ta klasa nie powinna być movable, not copyable? Jak ją skopiujesz to skopiujesz wskaźnik na storage i potem usuniesz jedną instancję to zdeletujesz, a w drugiej będzie
user image

0

mapa funkcji usuwających jest dlatego, że myślałem, że muszę usuwać coś, co nie jest wskaźnikiem na void
new jest dlatego, że staram się likwidować wszystkie ostrzeżenia(bez tego jest ostrzeżenie, że nie zwracam wartości)
a o tym, żeby było nie do kopiowania to zapomniałem :)
dziękuję za sprawdzenie kodu

1 użytkowników online, w tym zalogowanych: 0, gości: 1