1

我有一组共享指针。

我想创建一个函数来检查其中是否存在共享指针。

我认为我需要使用 set.count 来获取它。

但是我一直得到 0 ......即使共享指针存在于那里。

所以我的问题是:count 如何比较共享指针?

请记住,我是 C++ 新手,我可以提供代码,但代码很多。

编辑 2:检查建筑物并添加汽车的功能。

void Garage::addCar(Car& n, Building& m){
    shared_ptr<Building> mm(new Building(m));
    if (this->Buildings.count(mm) == 0){
        cout << m.name << " doesn't exist in " << this->name << "." << endl;
        return;
    }
    shared_ptr<Car> s(new Car(n));
    m.addCar(s);
    Cars.insert(s);
}

创建建筑物的功能

 Building Garage::create Building(string name){
    shared_ptr< Building> f_ptr(new  Building(name));
     Buildings.insert(f_ptr);
    return (*f_ptr);
}

类车库

class Garage {
public:
    Garage(string name);
    ~Garage();
    void admitCar(Car& n, Building& m);
    void dismissCar(Car& n, Building& m);
    void employEmployee(Employee& n, Building& m);
    void dismissEmployee(Employee& n, Building& m);
    Building createBuilding(string name);
    void deleteBuilding(Building&);
    private:
int nextIndex;
    string name;
    set<shared_ptr<Building> > Buildings;
    set<shared_ptr<Employee> > Employees;
    set<shared_ptr<Car> > Car;
}

每当我想在建筑物中添加汽车时,它都会说该建筑物不存在于那个车库中...

解决方案(我自己的):

bool Garage::hasBuilding(shared_ptr<Building> f){
    return (this->Buildings.count(f) != 0);
}

这是我创建的功能。有用。

我尝试了 Jonathan Wakely 和 LiKao 的方法,但它们对我来说有点太复杂了,而且我遇到了我自己无法解决的问题。

感谢您的帮助 :)

4

4 回答 4

3

您正在比较的指针是不同的,因为它们指向不同的对象。每当您说new Building将创建一座新建筑物时,尽管它与旧建筑物同名。因此,任何指向它的指针new Building都将不同于指向创建新建筑物的旧建筑物的任何指针。因此比较是正确的,新建筑不存在于集合中(您只是通过复制创建它,因此它不存在)。

您需要一个集合,可以根据指针指向的对象的属性进行比较。为此,您需要添加一个不同的比较函数来查看指向对象的指针。像这样的东西应该工作:

struct less_building  : std::binary_function<std::shared_ptr<Building>,std::shared_ptr<Building>,bool> {
  bool operator()( const std::shared_ptr<Building> & b1, const std::shared_ptr<Building> & b2 ) {
    return std::less( b1->name, b2->name );
  }
};

根据您对 的定义,这可能需要一些朋友声明Building,但一般来说,这样的事情就可以解决问题。

注1

在使用此技巧之前,请务必了解其含义。使用这个比较器意味着,Buildings你的集合中没有两个可以有相同的名字,不管他们可能有任何其他属性。之后,每对Building具有相同名称的 s 将被视为相同Building。根据您的建模领域,这可能是也可能不是您想要的。

如果您还想在名称相同的情况下比较其他属性,那么您必须将其添加到您的比较函子中。但是,这意味着不可能有两个Building具有相同属性集的 s。同样,这可能是也可能不是您想要的,具体取决于问题。

注2

通常混合和引用相同类型的对象非常不方便,std::shared_ptr这也会导致您遇到的问题。如果你std::shared_ptr在任何地方使用一个类型,你应该尽量保持一致并且只传递这些std::shared_ptr。原因是,从 a 转换std::shared_ptr为引用(例如使用operator*())很像单向函数。即,您可以从 a 获得参考,std::shared_ptr但很难std::shared_ptr从参考中取回。我可以想出两种方法来将std::shared_ptr它衰减为引用,但一种方法需要您更改对象(源自std::enable_shared_from_this<Building>std::shared_ptr与引用地址的无操作删除器)。所以我不会推荐任何一种方式。

相反,请选择适合您的问题域的设计,如上所示。或者防止std::shared_ptr腐烂。如果您将它们作为 (const)-references 传递,则std::shared_ptrthis 实际上不会比仅传递指针本身花费更多。

于 2012-06-17T13:18:54.780 回答
2

根据您的“编辑2”,我想我看到了您的误解。这是两个完全不相关的共享指针:

Building m;
shared_ptr<Building> a(new Building(m));
shared_ptr<Building> b(new Building(m));

它们不会在std::set.

但是,这些相关的指针:

Building m;
shared_ptr<Building> a(new Building(m));
shared_ptr<Building> b = a;

所以他们会在一个std::set.

本质上,比较是在指针上执行的,而不是在底层对象上。

于 2012-06-17T13:13:04.270 回答
1

我想创建一个函数来检查其中是否存在共享指针。

我不认为你这样做。

shared_ptr<Building> mm(new Building(m));
if (this->Buildings.count(mm) == 0){

当您刚刚在集合中创建共享指针时,它如何mm存在于集合中,并且它指向您刚刚创建的全新对象?在你创造他们和在系列中寻找他们之间,他们怎么会进入系列?

我认为您想Building通过比较建筑物的值来检查其中是否存在 a,您不在乎集合中是否存在特定对象或特定共享指针。

您可以搜索集合,与m每个元素指向的建筑物进行比较:

void Garage::addCar(Car& n, Building& m){
  bool found = false;
  for (auto& shptr : Buildings)
  {
    if (*sp == m)  // dereference shared_ptr to compare the Building 
    {
      found = true;
      break;
    }
  }

或在集合中使用自定义比较,如this answer

于 2012-06-17T13:27:34.970 回答
1

回答你的问题

count 如何比较共享指针?

比较是使用std::shared_ptr'sget()方法完成的,这意味着比较托管指针。值得一提std::set<std::shared_ptr<T>>的是,相关的比较是bool operator<

请参阅此处了解更多信息。

于 2012-06-17T13:01:32.087 回答