【问题标题】:Const ref versus const pointer as a data member for operator= overloadingconst ref 与 const 指针作为 operator= 重载的数据成员
【发布时间】:2019-10-18 08:21:00
【问题描述】:

具有“const int&”数据成员的类在重载 operator=(编译器为 g++)时会导致以下编译错误:

分配只读位置。

把数据成员改成'const int*'就可以了。

为什么?

#include <iostream>

using namespace std;
class B {
 private:
  const int& ir;
  //const int* ir;

 public:
  B(const int& i) : ir(i) {}
  //B(const int& i) : ir(&i) {}
  B& operator=(B& b) { ir = b.ir; return *this; }
};

g++ 错误信息:

opertostack.cpp:9:31: error: assignment of read-only location ‘((B*)this)->       B::ir’
        B& operator=(B& b) { ir = b.ir; return *this; }
                               ^~

【问题讨论】:

  • 你知道指针和引用的区别吗?
  • 您不能分配给 const 引用。而且您几乎肯定不希望将引用作为成员变量(const 或其他)。
  • 'ir' 可以正常重新分配。它是一个常量 &。我错过了什么吗?
  • @Jack 它不能“正常重新分配” - 这就是错误消息告诉你的内容。
  • 所有变量“只能初始化一次”——你需要弄清楚初始化和赋值之间的区别——这在 C++ 中非常重要。

标签: c++


【解决方案1】:

您不能重新绑定引用。一旦它们被创建,它们需要在其整个生命周期中引用同一个对象。

但是,您的代码存在更大的问题。让我们删除 operator=() 以便编译。然后我们实例化一个B:

B b(42);

b.ir 绑定到传递给构造函数的临时int。构造函数返回后,该临时文件不再存在。 b.ir 现在是一个悬空引用。它指的是一个不再存在的对象。

指针也无济于事。如果我们将B::ir 更改为const int* 并切换注释掉的代码,那么如上所述实例化B 的结果现在是一个悬空指针。它指向一个不再存在的临时对象。

因此,在这两种情况下,使用 B::ir 时都会出现未定义的行为。

你想要的只是一个普通的int 成员。在这种情况下,构造函数参数也不需要是引用。 int 与引用一样容易复制,因此您不会通过使用引用参数获得任何收益。最后,赋值运算符应该采用const 引用,这样您也可以从const B 对象进行赋值:

class B {
private:
    int ir;

public:
    B(const int& i) : ir(i) {}
    B& operator=(const B& b) { ir = b.ir; return *this; }
};

【讨论】:

    猜你喜欢
    • 2016-02-26
    • 1970-01-01
    • 2014-10-18
    • 1970-01-01
    • 2016-08-17
    • 1970-01-01
    • 2018-08-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多