简体   繁体   中英

Return templated smart pointer from constructor-like calls

I want to write some easy-to-call object initializiation and I would like those objects to be shared_ptr of MyClass.

Just for visualisiation purposes, imagine this class:

class MyClass
{
public:
  MyClass(int number);
  MyClass(wxString path);
}

int main()
{
  //For now, objects are created in c style like this:
  MyClass obj1("C:\\test");
  MyClass * obj2 = new MyClass(5);
}

Now I would like to change this with easy to use smart pointer initialization. My goal is something looking like a constructor call, so that very little has to be changed to update the old call to the new one:

Smart_MyClass obj1("C:\\test");
Smart_MyClass obj2(5);
//where Smart_MyClass is std::shared_ptr<MyClass> 

I could solve this with a function:

template<typename T>
inline Smart_MyClass Smart_MyClass_Fct(T t)
{
    return std::make_shared<MyClass>(t);
};

Smart_MyClass obj = Smart_MyClass_Fct(7);

How can I translate that into the form I need? I could think of using the operator(), that would require a struct/class and maybe inheritence of my actual class? And maybe casting it back to parent class? Pretty sure there is something more elegant. ;-)

You could try something along these lines:

template<typename T>
class SharedWrapper
{
public:
    template<typename... Args>
    SharedWrapper(Args... args) : 
        m_p{std::make_shared<T>(std::forward<Args>(args)...)}
    { }

    T& operator*() const noexcept { return *m_p; }
    T* operator->() const noexcept { return m_p.operator->(); }
    explicit operator bool() const noexcept { return static_cast<bool>(m_p); }

private:
    std::shared_ptr<T> m_p;
};

This just forwards the arguments of the constructor to the make_shared functions and then mirrors the interface of the smart pointer. (Here you might have to add additional forwarding methods as needed.)

With:

using Smart_MyClass = SharedWrapper<MyClass>;

you should get the desired behavior and can also use this for different classes.

However I don't see any possibility to have Smart_MyClass actually be a std::shared_ptr<MyClass> . Inheriting from shared_ptr is discouraged since it does not have a virtual destructor. This might also limit the usability of this approach.

Is there any reason besides style that makes you want to use this notation?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM