将共享指针与自定义相等运算符和std :: list一起使用时似乎存在问题。
我将以下示例代码放在一起以演示此问题。
在尝试编译之前:
我正在使用gcc version 4.5.2 20110127
使用以下命令行:
g++ -g -O0 -std=gnu++0x test.cpp
如果未启用c ++ 0x功能,则源将无法编译。
#include<list>
#include<boost/shared_ptr.hpp>
using std::list;
using std::shared_ptr;
using std::cout;
using std::endl;
class TestInt
{
public:
TestInt(int x);
bool operator==(const TestInt& other);
private:
int _i;
};
TestInt::TestInt(int x)
{
_i = x;
}
bool
TestInt::operator==(const TestInt& other)
{
if (_i == other._i){
return true;
}
return false;
}
class Foo
{
public:
Foo(TestInt i);
shared_ptr<TestInt> f(TestInt i);
private:
list<shared_ptr<TestInt>> _x;
};
Foo::Foo(TestInt i)
{
_x.push_back(shared_ptr<TestInt>(new TestInt(i)));
};
shared_ptr<TestInt>
Foo::f(TestInt i)
{
shared_ptr<TestInt> test(new TestInt(i));
int num = _x.size();
list<shared_ptr<TestInt>>::iterator it = _x.begin();
for (int j=0; j<num; ++j){
if (test == *it){
return test;
}
++it;
}
throw "Error";
}
int main(){
TestInt ti(5);
TestInt ti2(5);
Foo foo(ti);
foo.f(ti2);
std::cout << "Success" << std::endl;
}
我原本以为代码会以Success
结束,而是抛出。
在*
以及test
前面插入*it
修复了该问题,但我的理解是,当shared_ptr在其__a.get() == __b.get()
运算符中调用==
时它应该使用TestInt
的自定义相等运算符。我不明白为什么不是。这是一个错误吗?
提前致谢。
答案 0 :(得分:10)
这是因为当您比较两个shared_ptr<T>
时,您正在比较引用,即两个实例指向的内存地址,不是潜在价值观。
答案 1 :(得分:3)
您不是在比较TestInt对象,而是两个不同的指针,每个指针都指向自己的TestInt对象。所以基本上你的自定义等于运算符甚至都没有被调用。
你正在做的基本上是:
#include <iostream>
int main(int argc, char** argv) {
int* pi1 = new int(5);
int* pi2 = new int(5);
if (pi1 == pi2)
std::cout << "SUCCESS";
else
std::cout << "ERROR";
}
现在很明显pi1和pi2不相等而且代码完成了打印ERROR。
(我使用原始指针而不是shared_ptr这一事实并没有改变任何东西,但使逻辑更容易理解。与直接使用int而不是使用包装类相同。)