设置shared_ptr和设置函数计数

时间:2012-06-17 12:32:02

标签: c++ count set shared-ptr

我有一组共享指针。

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

我假设我需要使用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 个答案:

答案 0 :(得分: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的定义,但一般情况下这样做会有效。

<强> NOTE1

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

如果您想在名称相同的情况下比较其他属性,则必须将其添加到比较仿函数中。然而,这意味着没有两个Building具有相同的属性集。同样,这可能是你想要的,也可能不是,这取决于问题。

NOTE2

混合std::shared_ptr和对相同类型的对象的引用通常非常不方便,这也会导致您遇到的问题。如果您在任何地方使用std::shared_ptr类型,那么您应该尝试保持一致并且只传递这些std::shared_ptr。原因是,从std::shared_ptr转换为引用(例如使用operator*())非常类似于单向函数。即您可以从std::shared_ptr获取引用,但很难从引用中获取std::shared_ptr。我可以想到两种方法可以在将std::shared_ptr衰减到引用后返回std::enable_shared_from_this<Building>,但是需要你更改对象(从std::shared_ptr派生)而另一种只是闻起来非常糟糕的代码(使用no-op删除器创建一个新的std::shared_ptr到引用的地址)。所以我不推荐这两种方式。

相反,要么选择适合您的问题域的设计,如上所示。或者让std::shared_ptr不要腐烂。如果你将它们作为(const) - 引用传递给{{1}},这实际上不会比仅仅绕过指针本身花费更多。

答案 1 :(得分: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内匹配。

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

答案 2 :(得分:1)

回答你的问题

  

count如何比较共享指针?

使用std::shared_ptr的{​​{1}}方法进行比较,这意味着比较了托管指针。关注get(),相关比较为std::set<std::shared_ptr<T>>

有关详细信息,请参阅here

答案 3 :(得分:1)

  

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

我不认为你这样做。

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

当你 在那里创建共享指针mm时,它如何存在,它指向一个全新的对象,你只是创造?他们怎么能在你创建它们和在集合中寻找它们之间进入集合?

我想你想检查一下是否存在Building,通过比较建筑物的值,如果特定对象或特定共享指针位于其中,则关心集。

您可以搜索集合,将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