澄清智能指针的操作符*和操作符 - >超载

时间:2014-04-03 10:28:07

标签: c++ pointers operator-overloading smart-pointers

自从我使用c ++以来,它已经通过了很多,所以这里(问题上是愚蠢的)问题:

基本的智能指针Object应该像普通的指针一样,所以在典型的实现中,我们将*->运算符添加到对象中,如下所示:

template <class T> class auto_ptr
{
    T* ptr;
    public:
    explicit auto_ptr(T* p = 0) : ptr(p) {}
    ~auto_ptr()                 {delete ptr;}
    T& operator*()              {return *ptr;}
    T* operator->()             {return ptr;}
   // ...
};

现在,在我的知识中,c ++ *运算符(取消引用)代表:&#34;通过ptr&#34;的值获取堆中指向的值。 (是不是?),*ptr的类型应为T。那么为什么我们会返回一个地址?

T& operator*()              {return *ptr;}

而不是:

T operator*()              {return *ptr;}

其次,通过以下代码段:

void foo()
{
    auto_ptr<MyClass> p(new MyClass);
    p->DoSomething();
}

现在,如何通过编写ptr->DoSomething()来访问p->DoSomething()方法?从逻辑上讲,我会写错了代码:

p->->DoSomething();

由于p->返回T*,然后我需要另一个->运算符来访问DoSomething()方法。

感谢您的回答/澄清,并对最终糟糕的英语表示抱歉。

3 个答案:

答案 0 :(得分:5)

在C ++中,当你评估一个函数时,你得到一个值(除非函数的返回类型是void)。值的类型始终是对象类型。因此,当您说f()时,该表达式的类型为T。但是,有不同的类别值:

T    f();    =>   f() is a prvalue, passed along by copy
T &  f();    =>   f() is an lvalue, the same object that is bound to "return"
T && f();    =>   f() is an xvalue, the same object that is bound to "return"

因此,如果您希望函数生成您不想复制的现有值,则必须将函数的返回类型声明为引用类型之一。如果返回类型不是引用类型,则将生成返回值的副本,并且调用者只能看到该副本。

答案 1 :(得分:2)

您不必编写p->->DoSomething的原因是operator->递归,直到找到不是指针的内容T*

p->找到T*这是一个指针,因此它会向下移动另一个级别并找到MyClass - 对象,因此它会停止并对其执行正常的operator.

请注意,在这种情况下,智能指针不被视为指针。

答案 2 :(得分:1)

取消引用运算符返回引用,因为这样你就可以做到。

*somePointer = someValue;

并且somePointer指向的值将更改为someValue。如果按值返回,则上面的表达式将具有分配给的临时值,然后该临时值将被销毁并且更改将丢失。