像shared_ptr这样的智能指针可以像使用*
和->
运算符的普通指针一样使用。
书中说->
运算符返回shared_ptr存储的指针。因此,您可以使用它来访问此指针指向的对象。但我在这里很困惑。请看下面的代码。
class A
{
public:
A(int v = 20){val = v;}
int val;
}
A* p1 = new A;
std::cout<<p1->val; //This is common sense
boost::shared_ptr<A> p2(new A);
std::cout<<p2->val; //This is right
//My question is that p2-> returns the pointers of the object, then maybe another
//-> should be used?
//like (p2->)->val?
答案 0 :(得分:10)
这很神奇。好吧,更像是一个特例。标准说
13.5.6班级成员访问[over.ref]
1
operator->
应该是不带参数的非静态成员函数。它实现了使用->
的类成员访问语法。post fi x-expression - &gt; templateopt id-expression
post fi x-expression - &gt;伪析构函数名称如果
x->m
类型为(x.operator->())->m
的类对象x
,则表达式T
被解释为T::operator->()
存在并且如果操作符被重载决策机制选择为最佳匹配函数(13.3)。
也就是说,在重载运算符的结果上再次调用operator->
。如果那个也被重载,它会递归地继续,直到原始指针是结果并且内置的operator->
被调用。
这并不意味着结果不能是任意类型 - 它可以,但是你只能用函数调用语法调用它:
struct X {
int operator->() { return 42; }
};
int main()
{
X x;
x.operator->(); // this is OK
}
答案 1 :(得分:1)
幸运的是,C ++的设计者实现了这一点,并改变了重载的中缀->
运算符的语义,意味着运算符返回的指针插在->
的左侧。运算符,然后像往常一样访问该成员。
如果您要明确调用->
运算符,则需要插入额外的->
,但是:
std::cout << p1.operator->()->val;
答案 2 :(得分:0)
operator ->
的返回值与p2->val
返回的值不同。 operator ->
的返回值是一个指针,用于访问val
成员,因此p2->val
按预期工作。