我有一组共享指针。
我想创建一个检查共享指针是否存在的函数。
我假设我需要使用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的方式,但是对我来说它们有点太复杂了,我遇到了一些问题,我自己也无法解决。
感谢您的帮助:)
答案 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。