C 超负荷取消运算符

C++ overloading dereference operators

本文关键字:运算符 取消 超负荷      更新时间:2023-10-16

我对C 的新手相对较新,仍然试图掌握语法。我一直在看一些操作员超载示例,最近是智能指针实现。这是我正在查看的一个非常通用的例子:

template < typename T > class SP
{
    private:
    T*    pData; // Generic pointer to be stored
    public:
    SP(T* pValue) : pData(pValue)
    {
    }
    ~SP()
    {
        delete pData;
    }
    T& operator* ()
    {
        return *pData;
    }
    T* operator-> ()
    {
        return pData;
    }
};

超负荷取消运算符时,为什么Type t&amp;?同样,当结构重载过载时,为什么T*?

类型

deReference Operation(*)过载与任何其他操作员过载一样有效。如果您想能够修改剥离值,则需要返回非const参考。这样,*sp = value实际上将修改sp.pData指向的值,而不是编译器生成的临时值。

结构解除操作员(->)过载是操作员超载的特殊情况。实际上,将操作员调用循环,直到返回真正的指针为止,然后再用真正的指针。我想这只是他们实施它的唯一途径,结果有些刺耳。但是,它具有一些有趣的属性。假设您有以下课程:

struct A {
    int foo, bar;
};
struct B {
    A a;
    A *operator->() { return &a; }
};
struct C {
    B b;
    B operator->() { return b; }
};
struct D {
    C c;
    C operator->() { return c; }
};

如果您有一个类型D的对象d,调用d->bar将首先调用D::operator->(),然后是C::operator->(),然后是B::operator->(),然后以正常方式将真正的指针返回到struct A,其bar成员被撤回。请注意,在以下内容中:

struct E1 {
    int foo, bar;
    E1 operator->() { return *this; }
};

调用e->bar,其中eE1类型,会产生无限环路。如果您想实际解释e.bar,则需要执行此操作:

struct E2 {
    int foo, bar;
    E2 *operator->() { return this; }
};

总结:

  1. 在超载解释操作员时,该类型应为T&,因为这是修改pData指向的值所必需的。
  2. 在结构解除过载时,该类型应为T*,因为此操作员是一种特殊情况,这正是它的工作方式。

取消操作员的目的是取消指针并返回对象引用。因此,它必须返回参考。这就是为什么它是t&amp;。

引用操作员的目的是返回指针,因此返回T*。

这是因为指针包含一个变量引用的地址,它将为其存储的地址提供引用(或说出lvalue折扣)。例如int x; int *p; p=&x;现在x*p可以互换使用。如果您执行x =4;*p = 4;,则两者都会产生相同的结果。*p用作x的引用,就像普通参考int& t = x;一样。

下一件事结构解除运算符。该操作员可以通过指向类的指针访问成员变量。在上面的示例中,成员是T* pData;,因此使用此操作员将访问pData,而pDataT*,因此返回类型为T*。如果上述示例中的pDataT,则返回类型将是T

超载运算符只是功能

超载操作员时,您可以自由地基本返回任何东西(就像其他功能一样),而Pointer的 ->除外,以这种方式有些特别。

在您显示的示例中,智能指针,您的目标是模仿指针的语法(指针语义)。然后对于语法,例如:

*p = 2;

间接operator*返回A non-const Reference 到对象,我们能够通过operator*修改。实际上,通常用于代理以相同的方式键入类,这是一种约定 - 但是从理论上讲,您可以返回任何内容。

Pointer的成员运算符->有点棘手。请参阅此答案。

我们正在制作智能指针,我们的目的是使用此t&amp;(参考)或具有灵活性的T*(指针)。

for T* operator->():

T* operator-> ()
{
  return pData;
}
arrow operator (->) is a shorthand for (*p) and hence we return *pData which is of   type T*. 
here we are Overloding arrow operator so that members of T can be accessed like a pointer.

t&amp;操作员*():

T& operator* ()
{
  return *pData;
}
    * is "value at address" operator, here we are Overloding * (pointer) operator so 
    that members can be accessed  through a reference (T&).

我们可以通过运算符过载来改变操作员的行为,但不建议进行。超载运算符的行为应与其基本功能一样接近。