unique_ptr如何支持" dot"和"箭头"调用和未定义的方法?

时间:2015-11-24 19:08:56

标签: c++ unique-ptr

据我所知,在C ++中,任何对象的任何方法调用都必须在其类定义中预先定义。因此,当我查看std::unique_ptr时,它会变得有趣。

似乎unique_ptr同时支持" dot" (例如reset())和" arrow"操作。然而," dot"用于指示,而#34;箭头"是对象/引用(我们可以做ptr->MethodThatTheEncapsulatedClassSupports())。那么unique_ptr如何既可以是指针又可以是对象?

第二个有趣的部分是,传递给unique_ptr的类可以是任意的。我可以在我的类中定义任何方法,似乎我们可以直接在unique_ptr实例上调用该方法。由于C ++没有像Ruby那样的动态方法调度机制(AFAIK C ++方法调用是静态的,必须定义,这是有道理的,因为C ++直接编译成机器代码),这甚至可以实现吗?

4 个答案:

答案 0 :(得分:2)

这是因为CreateA可以重载以返回另一个对象或指针。然后以递归方式与operator->一起使用。

operator->

答案 1 :(得分:1)

我能想到的最简单的smartpointer实现是:

#include <iostream>     
struct A { 
    void moo(){std::cout << "MOO" << std::endl;}
};

template <typename T>
struct DumbPointer {
    T* t;
    DumbPointer(T* t) : t(t) {}
    ~DumbPointer(){delete t;}
    T* operator->(){return t;}
    void moo(){std::cout << "MOOMOO" << std::endl;}
};     

int main() {
    DumbPointer<A> f = DumbPointer<A>(new A());
    f.moo();              // prints MOOMOO
    f->moo();             // prints MOO
    // your code goes here
    return 0;
}

重载->运算符,使其看起来像一个指针,而实际上DumbPointer本身就是一个对象。有关重载的详细信息,请参阅例如here。相关部分是:

  

如果是用户定义的运算符 - >提供,运营商 - &gt;再次调用它返回的值,直到操作符 - >到达,返回一个普通指针。之后,内置语义应用于该指针。

答案 2 :(得分:0)

类传递给unique_ptr的原因可能是任意的,因为该类是模板参数。您应该阅读有关模板及其工作原理的信息,但实际上在编译时会自动为您使用的每个类创建一个unique_ptr版本。

方式 - &gt;工程是运营商重载。 unique_ptr的实例不是指针,而是包含指针的对象,并且具有允许您使用的运算符重载 - &gt;访问该指针指向的对象中的数据。 。访问unique_ptr本身的方法。

答案 3 :(得分:0)

我发现James O. Coplien的解释在他的书Advanced C++中非常明确和易懂。这是解释;

重载operator->与其他重载的C ++运算符不同。对于所有其他运算符,定义运算符实现的主体可以最终控制从操作返回的值。对于operator->,返回值是一个中间结果,然后应用->的基本语义,从而产生结果。所以,

class B {
    ...
};

class A {
public:
    B *operator->();
};

int main() {
    A a;
    ... a->b ...
}

表示以下内容:

  1. 在对象A::operator->()上调用a;
  2. x类型的临时B*捕获该调用的返回值;
  3. 评估x->b,产生结果。
  4. 此处,b可以由class B的任何成员,数据或函数替换。如果class B重载operator->,则会再次应用上述三个步骤。