【问题标题】:How does operator [] of an address of variable work?变量地址的运算符[]如何工作?
【发布时间】:2019-11-18 17:29:20
【问题描述】:

例如:

int x = 5;
std::cout<<(&x)[0]<<std::endl; -> prints 5

我在一本书中找到了 3DVector 的这种表示:

struct Vector3D{
float x,y,z;
Vector3D() = default;
Vector3D(float a, float b, float c) : x(a), y(b), z(c) {}
float & operator[](int i){
return ((&x)[i]);
}
};

如果将其用作:

    Vector3D myVec(0,2,3);
    std::cout<<myVec[0]<<std::endl;
    std::cout<<myVec[1]<<std::endl;
    std::cout<<myVec[2]<<std::endl;

它将打印 x、y、z 的值

它是如何工作的?这安全吗?

【问题讨论】:

  • 为什么我必须确定声明的变量是一一存在的?或者这只适用于这种特殊情况?
  • 要获得安全的东西,必须使用offsetof。另请注意“offsetof 无法在标准 C++ 中实现,需要编译器支持”,因为它取决于结构的成员填充
  • @ChrisMM “它们以这种方式存储在内存中”可能但不一定。它不是“通常被认为是不安全的”。这只是未定义的行为,根据定义,它总是不安全,永远不会有用或有帮助。
  • @ChrisMM 我不太明白。 “你会看到问题......”相当具有误导性。有可能看不到任何问题

标签: c++ overloading operator-keyword


【解决方案1】:

当你执行&amp;x 时,你会得到一个指向x 的指针。当您执行pointer[N] 时,编译器所做的就是将其转换为*(pointer + N)。在您的代码中,因为N0,所以我们留下了*(&amp;x),它只是取消引用我们刚刚创建的指针,返回变量本身。


您在其中找到的代码实际上是未定义的行为。当他们这样做时

float & operator[](int i){
    return ((&x)[i]);
}

他们假设类中没有填充,并将 3 个单独的成员视为一个数组。但不能做出这种假设,并且该访问被明确称为标准中未定义的行为。

【讨论】:

  • 更具体地说,他们假设类成员之间没有填充。事实上,在实践中,成员之间很可能没有填充。但是无论是否有填充,行为仍然是不确定的。
  • 注意:这种类型的未定义行为(假设确实没有填充)的实际后果包括混淆优化器,因此您的数字实际上不会被写入任何地方,或者以便它读取 x 而不是 y,但仅在启用了某些选项的某些编译器上。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 2014-12-26
  • 2011-05-31
相关资源
最近更新 更多