C++:无法从 const 方法 return a shared_ptr 到对象

C++: Cannot return a shared_ptr to an object from a const method

我正在尝试 return shared_ptrGroup 类型的对象,从声明中具有 const 的方法(此项目中的要求). Group对象存储在class属性mySet<Group> groups中,mySet只是std::set的一个实现(也是一个要求)。我已尝试从各个角度处理该任务,但似乎找不到可行的解决方案。

我省略了不相关的方法和属性以使其最小化和清晰。

typedef std::shared_ptr<Group> GroupPointer;
typedef mySet<Group>::const_iterator cgIterator;

class Clan{
    std::string name;
    mySet<Group> groups;
    public:
    const GroupPointer& getGroup(const std::string& group_name) const;
};

class Group{
   std::string name;
   public:
   const std::string& getName() const;
};

const GroupPointer& Clan::getGroup(const std::string& group_name) const{
    cgIterator  itr = groups.begin();
    for(; itr != groups.end(); itr++){
        if((*itr).getName() == group_name){
            GroupPointer* pptr = new GroupPointer(new Group(*itr));
            return *pptr;
        }
    }
}

首先,不要在堆上分配指针本身。 使用 std::make_shared()

GroupPointer pptr = std::make_shared<Group>(Group(*itr));

因为共享指针的这个实例将超出范围并被销毁,所以最好return按值而不是引用它。

让我们看看你目前在做什么returning

GroupPointer* pptr = new GroupPointer(new Group(*itr));
return *pptr;

您有一个 参考 动态分配 shared_ptr,目前是唯一 副本 你的集合的一个元素的所有者。

有几个明智的选择,还有一些不太明智的选择

  • groups更改为mySet<std::shared_ptr<Group>>
    • 您应该认真考虑将 Clan::getGroup 的 return 类型更改为 std::shared_ptr<Group>。你会写一个方法吗Group * const & someMethod(...)?
  • Clan::getGroup改为return一个Group const &

当你找到一个元素时,这两个都允许你return *itr;

不太理智

  • return std::make_shared(*itr);

std::set 拥有它的元素。 std::shared_ptr 拥有(连同其他 shared_ptrs)它指向的内容。你不能同时拥有两者。在此设置中使用 std::shared_ptr 的唯一明智方法是使用 std::set<std::shared_ptr<Group>>