Quantcast
Channel: Recent Questions - Stack Overflow
Viewing all articles
Browse latest Browse all 16420

C++ My smart pointer implementation for polymorphism without the need to maintain clonability - Is it any good? [closed]

$
0
0

I recently wanted to use a list of different derived classes, as one does quite often, but also wanted it to be copyable. Because of this I couldn't use something like std::unique_ptr or std::shared_ptr since when copying, I want not only the pointer but also the pointed to object in memory to be duplicated.After some research I found out about the clone pattern, the use of something called CRTP, and some other (though rather unconvenient) ways. Although a clone method in every class makes sense, it seems very redundant because it's the same code every time. Regarding CRTP I thought a new class is a bit much as you know the type of the currently stored derived through the set method template (see code) and would just need to save it for creating a new object of it later when copying.

I now implemented my own version which solves my copy problem but I am wondering why I haven't found something like this proposed elsewhere? Are there any drawbacks to using this, or is there anything I've missed with this?I don't know if there even is a way of storing which datatype something is (typedef and decltype are not settable variable-alikes), so I used a std::function whose return type is dynamically overwritten.

Here's the implementation I have:(Sure, there are still some things to add, like a direct assignment operator overload, and stuff, but for now it's okay like this)

template <typename BaseType>class PolyPtr {private:    BaseType* basePtr;    std::function<BaseType*()> cloneFunc;public:    PolyPtr() {        basePtr = nullptr;    }    PolyPtr(const PolyPtr &pCopyFrom) {        basePtr = pCopyFrom.cloneFunc();    }    ~PolyPtr() {        clear();    }    BaseType* get() {        return basePtr;    }    template <typename DerivedType>    DerivedType* getDerived() {        DerivedType* derivedPtr = dynamic_cast<DerivedType*>(basePtr);        return (derivedPtr ? derivedPtr : nullptr);    }    template <typename DerivedType>    void set(DerivedType pNewObject) {        clear();        basePtr = new DerivedType(pNewObject);        cloneFunc = [basePtr = this->basePtr]() -> DerivedType* {return new DerivedType(*static_cast<DerivedType*>(basePtr));};    }    void clear() {        delete basePtr;        basePtr = nullptr;        cloneFunc = []() -> BaseType* {return nullptr;};    }};

Viewing all articles
Browse latest Browse all 16420

Latest Images

Trending Articles



Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>