引用具有禁用的复制构造函数/分配的对象

问题描述

在我的应用程序中,我有一个对象列表。由于我必须只有一个实例,因此我禁用了复制构造函数和赋值运算符。仍然允许移动对象。但是,由于我对对象执行了各种操作,因此需要存储指向其中一个的指针。在我将指针用于此目的之前,但现在我想使用一个引用。

由于某些原因,我无法重新分配参考。错误

error: overload resolution selected deleted operator '='
candidate function has been explicitly deleted

演示该问题的示例代码

#include <iostream>

class Item
{
public:
    Item() { n = (++Item::counter); }
    Item(const Item&& other) { n = std::move(other.n); }
    Item(const Item& other) = delete;
    Item& operator=(const Item& other) = delete;
    int Get() { return n; }
private:
    int n;
    static int counter;
};

int Item::counter = 0;

int main()
{
    Item i1;
    Item i2;

    Item *p = &i1;
    printf("%d\n",p->Get());

    p = &i2;
    printf("%d\n",p->Get());

    Item &r = i1;
    printf("%d\n",r.Get());

    r = i2; // here I get the error
    printf("%d\n",r.Get());

    return 0;
}

好的,我能理解我是否在类似以下内容上出错:

Item i3 = i2;

即如果是真正的任务。但是在这里,我只想存储对该对象的引用,而不是将其分配或复制到另一个对象。

所以我的问题是如何存储对未复制对象的引用以避免指针?

解决方法

在C ++中,引用不可重新绑定。这是什么意思?这意味着一旦创建引用,就无法更改该引用所引用的对象。它具有主要含义-例如以下代码:

Item i1;
Item i2;
Item &r = i1;
r = i2; 

在逻辑上等效于此:

Item i1;
Item i2;
i1 = i2; 

现在应该可以理解为什么编译器的赋值运算符有问题。什么是要做?您可以使用std::reference_wrapper,它是您想要的-可重新绑定的引用类型:

Item i1;
Item i2;
auto r = std::ref(i1);
r = std::ref(i2);