Abh*_*jit 7 c++ pointers shared-ptr unique-ptr c++11
我有一个带有指针成员的基类.我必须做出有根据的猜测,以确定它应该是a unique_ptr还是a shared_ptr.他们似乎都没有解决我的特定用例.
class Base
{
public:
    Base(): pInt(std::unique_ptr<int>(new int(10))) {};
    virtual std::unique_ptr<int> get() = 0;
    //Base(): pInt(std::shared_ptr<int>(new int(10))) {}; // Alternate implementation
    //virtual std::shared_ptr<int> get() = 0; // Alternate implementation
private:
    std::unique_ptr<int> pInt;
    //std::shared_ptr<int> pInt; // Alternate implementation
};
基类已导出到Derived1和Derived2.前者返回后者返回本地对象的unique_ptr成员.pIntunique_ptr
class Derived1: public Base
{
public:
    Derived1() {};
    virtual std::unique_ptr<int> get()
    {
        //return std::move(pInt);  Will compile but the ownership is lost
        return pInt;
    }
private:
    std::unique_ptr<int> pInt;
};
class Derived2: public Base
{
public:
    Derived2() {};
    virtual std::unique_ptr<int> get()
    {
        std::unique_ptr<int> pInt(new int());
        return pInt;
    }
private:
    std::unique_ptr<int> pInt;
};
Derived1get的实现不会隐式转移所有权,因为成员指针变量不是eXpiring值,而Derived2实现可以.标准中详细记录了此行为
见12.8§34和§35:
当满足某些条件时,允许实现省略类对象的复制/移动构造[...]复制/移动操作的省略,称为复制省略,允许在...中的返回语句中.具有类返回类型的函数,当表达式是非易失性自动对象的名称时,具有与函数返回类型相同的cv-nonqualified类型[...]
当满足复制操作的省略标准并且要通过左值指定要复制的对象时,首先执行用于选择复制的构造函数的重载决策,就好像该对象由右值指定一样.
然而,如果我通过the明确地转移所有权std::move,则成员指针将来将无法使用.
或者,我必须将指针定义为,shared_ptr但这将是实现的额外开销Derived2::get.
注意应该考虑Derived2::get更多的发生比较,Derived1::get因此使用的设计决定std:: shared_ptr可以产生相当大的相对影响.
小智 5
您的Derived1案件无法以您想要的方式处理unique_ptr.您需要多个智能指针指向同一资源.unique_ptr根本不是一个选择.没有办法解决这个问题.
你可以坚持使用一个unique_ptr成员,但让你的函数返回一个原始指针.
virtual int *get() = 0;
这对你的Derived2班级很麻烦,因为不清楚调用者是否应该释放指向内存.我建议你不要这样做.
您可以shared_ptr按照建议使用成员,并使您的函数返回该成员.这在你的Derived2班级中是完全正常的,但正如你所指出的那样,次优.
不过,它仍然是最干净的解决方案.对于只知道他们已经拥有的呼叫者Base,您需要某种方式通知他们(手动或通过返回的类型)他们完成后应该做什么get(),所以你unique_ptr<int>无论如何都无法返回.
函数返回的唯一方法unique_ptr<int>是,如果调用者已经知道你有一个Derived2.但是,您可以添加一个新成员:
virtual shared_ptr<int> get() {
  return get_unique();
}
virtual unique_ptr<int> get_unique() {
    std::unique_ptr<int> pInt(new int());
    return pInt;
}
我只会这样做,如果分析显示该shared_ptr<int> get()成员实际上增加了可衡量的开销.您的shared_ptr<int>实施很有可能是充分的,性能方面的,然后可读性应该是不添加新成员的原因.