运营商 - >智能指针的返回值

时间:2013-12-14 12:44:31

标签: c++ pointers

像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? 

3 个答案:

答案 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;

Demo on ideone

答案 2 :(得分:0)

operator ->的返回值与p2->val返回的值不同。 operator ->的返回值是一个指针,用于访问val成员,因此p2->val按预期工作。