据我所知,在C ++中,任何对象的任何方法调用都必须在其类定义中预先定义。因此,当我查看std::unique_ptr
时,它会变得有趣。
似乎unique_ptr
同时支持" dot" (例如reset()
)和" arrow"操作。然而," dot"用于指示,而#34;箭头"是对象/引用(我们可以做ptr->MethodThatTheEncapsulatedClassSupports()
)。那么unique_ptr
如何既可以是指针又可以是对象?
第二个有趣的部分是,传递给unique_ptr
的类可以是任意的。我可以在我的类中定义任何方法,似乎我们可以直接在unique_ptr
实例上调用该方法。由于C ++没有像Ruby那样的动态方法调度机制(AFAIK C ++方法调用是静态的,必须定义,这是有道理的,因为C ++直接编译成机器代码),这甚至可以实现吗?
答案 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 ...
}
表示以下内容:
A::operator->()
上调用a
; x
类型的临时B*
捕获该调用的返回值; x->b
,产生结果。此处,b
可以由class B
的任何成员,数据或函数替换。如果class B
重载operator->
,则会再次应用上述三个步骤。