为什么它会愚蠢地覆盖& amp;操作员并返回*此*"?

时间:2013-03-17 18:45:45

标签: c++ operator-overloading

当然,我想不出任何理由为什么我想要覆盖一元&运算符,但在https://stackoverflow.com/a/4542813/368896海报中说明了某些类X

  

......除非X做了一些非常愚蠢的事情,比如超载一元和一些   返回此

(注意:我认为此评论指的是&运算符返回this的事实,而不是覆盖&运算符本身的事实。)

当我想到这个评论时,我发现“返回此”是完全 &运算符所做的事情 - 即使在多重继承的情况下也是如此。

鉴于有人可能永远不会希望覆盖一元&运算符,但是为什么让它返回this是愚蠢的(如果你决定覆盖它) )?

2 个答案:

答案 0 :(得分:7)

  

我发现“归还这个”正是&运营商

你是对的,虽然C ++也禁止获取临时对象的地址

the question you reference的上下文中,关于确定对象是否是临时对象:

如果您实现自己的operator &返回this,您将通过告诉编译器&(expression)始终有效来绕过此保护。考虑:

struct foo
{
};

struct bar
{
    bar* operator&()
    {
        return this;
    }
};

template <typename T>
void test(const T*)
{
    // no temporaries, can't take address of temporary...right?
}

int main()
{
    foo x;
    test(&x); // okay, x is an lvalue

    /*
    test(&(foo())); // not okay, cannot take address of temporary
    */

    bar y;
    test(&y); // still okay, y is an lvalue

    test(&(bar())); // huh?! not taking address of temporary, calling operator&
}

答案 1 :(得分:2)

确实用途非常有限。 例如,一个用例是smartpointers,因为它们经常在Direct3D中用于包装IUnknown对象。

我认为你不熟悉Direct3D,所以我会再谈一谈。 许多Direct3D类派生自IUnknown,在使用它们之后,必须调用Release。是的,D3D内部使用引用计数。人们往往忘记打电话给Release,这真的很乏味。所以我所做的就是将IUnknown包装成smartpointer,这将在幕后发布。

smart_pointer<ID3D11Device> device = // .. 

因此,通过声明&device您不想要smart_pointer<ID3D11Device>的地址,您需要ID3D11Device的地址。

template <class T>
class com_ptr
{
private:
    T *inst;

public:
   // many other methods/overloadings

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

底线:这样,您可以在析构函数中调用Release,而不必在其余代码中关注它。

第2行:更好的方法是添加一个返回实习对象的get()方法。

    T** get()
    {
        return &inst;
    }