繁体   English   中英

访问由std :: shared_ptr包装的类的运算符重载

[英]accessing operator overloading of class which is wrapped by std::shared_ptr

这个想法是,我希望由std::shared_ptr包装的类仍然可以像不是指针一样被使用,例如,包装完类后仍可以使用在类中定义的operator =通过std::shared_ptr

例如

template <class Ty> class shared_ptr_proxy : public std::shared_ptr<Ty> {
public:
    template<class Other> shared_ptr_proxy& operator=(const Other& rhs)
    {
        (*this->get()) = rhs;
        return *this;
    }
    template<class Other> explicit shared_ptr_proxy(Other * ptr) 
        : std::shared_ptr<Ty>(ptr){};
};

// usage :
shared_ptr_proxy<float> obj = shared_ptr_proxy<float>(new float);
obj = 3.14;

它的工作,但有没有一种方法,我不需要创建shared_ptr_proxy或从std::shared_ptr继承一个类?

如果我这样做,是否有需要注意的警告?

这取决于您想要的代理。 完整的代理可能会使它看起来完全像您具有的值,因此您需要提供转换运算符。

但是,在这种情况下,从shared_ptr继承可能不是一个好主意,因为您可能正在继承要依赖隐式转换的函数。

比较排序项目的方式:

#include <memory>
#include <vector>
#include <algorithm>
#include <iostream>

template <class Ty> class shared_ptr_proxy   {
    std::shared_ptr<Ty> ptr;
public:
    template<class Other> explicit shared_ptr_proxy(Other * p) 
        : ptr(std::shared_ptr<Ty>(p)){};

    template<class Other> shared_ptr_proxy& operator=(const Other& other)
    {
        *ptr = other;
        return *this;
    }

    operator Ty& () { return *ptr; }
    operator const Ty& () const { return *ptr; }
};

int main()
{
    std::vector<shared_ptr_proxy<int> > vec {
        shared_ptr_proxy<int>(new int(10)), 
        shared_ptr_proxy<int>(new int(11)), 
        shared_ptr_proxy<int>(new int(9))
    };
    vec.back() = 8;  //use assignment
    std::sort(vec.begin(), vec.end());  //sort based on integer (not pointer) comparison
    for (unsigned i = 0; i != vec.size(); ++i) {
        std::cout << vec[i] << ' ';  //output stored values
    }
}

#include <memory>
#include <vector>
#include <algorithm>
#include <iostream>

template <class Ty> class shared_ptr_proxy : public std::shared_ptr<Ty>   {
public:
    template<class Other> explicit shared_ptr_proxy(Other * p) 
        : std::shared_ptr<Ty>(p){};

    template<class Other> shared_ptr_proxy& operator=(const Other& other)
    {
        *this->get()= other;
        return *this;
    }

    operator Ty& () { return *this->get(); }
    operator const Ty& () const { return *this->get(); }
};

int main()
{
    std::vector<shared_ptr_proxy<int> > vec {
        shared_ptr_proxy<int>(new int(10)), 
        shared_ptr_proxy<int>(new int(11)), 
        shared_ptr_proxy<int>(new int(9))
    };
    vec.back() = 8;  //the only thing that works
    std::sort(vec.begin(), vec.end());  //sort based on pointer values
    for (unsigned i = 0; i != vec.size(); ++i) {
        std::cout << vec[i] << ' ';  //outputs addresses
    }
}

operator=必须是您正在重载的类的成员。 所以不,您不能真正做到非侵入式。

不,您不能透明地执行此操作,如果可以的话,可能会非常令人困惑。

抱歉,我不认为没有继承或没有自定义包装程序就无法摆脱shared_ptr ,不能在shared_ptr定义之外重载operator = ,并且由于shared_ptr的性质,在这种情况下不建议继承。 但是,如果您编写一个自定义包装器,则可以使其足够通用,以使其适用于每种类型。

这仅在C ++ 11中是可能的,即使在那里也很困难。 您需要使用decltypestd::declval来推断运算符的返回类型,并需要使用rvalue引用和std::forward来完美地转发参数。 有关示例,请参见此问题及其答案。

如该问题中所述,我实现了一个指针包装器类: http : //frigocoder.dyndns.org/svn/Frigo/Lang/ref

但是,与您想要的相比有一些区别:

  • operator = (ref&)operator = (ref&&)仅复制指针。 但是,由于这个原因以及代理的复制构造函数,隐式operator = (const T&)了复制构造和指针复制,而不是赋值或获取地址。 这是我的自觉选择,如果共享对象,分配会产生问题,并且从堆栈分配的对象获取指针是不安全的。

  • 由于GCC的未实现功能,采用复合赋值运算符(如operator +=的返回类型不起作用。 这是没有问题的,因为它们被重新解释: x += y调用x = (x + y) ,进行复制/移动构造和指针复制。 这也是我的有意识的选择,以保持共享对象不变。

  • 使用Boehm GC收集的垃圾(而不是参考文献)进行计数。 这也是我的自觉选择,引用计数是垃圾收集的非常糟糕的选择。

解引用共享指针:

std::shared_ptr<float> obj(new float);
*obj = 3.14;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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