这个C ++语法是什么意思,为什么它起作用?

时间:2010-09-03 02:44:39

标签: c++ operator-overloading

我正在浏览OpenDE的源代码,我在类上遇到了数组索引运算符'[]'的一些奇怪的语法用法。这是一个显示语法的简化示例:

#include <iostream>

class Point
{
public:
    Point() : x(2.8), y(4.2), z(9.5) {}

    operator const float *() const
    {
        return &x;
    }

private:
    float x, y, z;
};

int main()
{
    Point p;
    std::cout << "x: " << p[0] << '\n'
              << "y: " << p[1] << '\n'
              << "z: " << p[2];
}

输出:

x: 2.8
y: 4.2
z: 9.5

这里发生了什么?为什么这种语法有效? Point类不包含重载operator [],此处此代码试图自动转换为浮动某处。

我以前从未见过这种用法 - 至少可以说这看起来很不寻常和令人惊讶。

由于

3 个答案:

答案 0 :(得分:17)

p被隐式转换为const float* const,指向x。因此*px*(p+1)y,依此类推。 当然,以这种方式做这是一个非常奇怪的想法(并且令人困惑!)。通常最好将x,y和z存储在一个数组中,如果他们真的想以这种方式做事,就可以获得整个数组的函数。

答案 1 :(得分:8)

这里的想法是通过下标或名称来访问Point的成员。但是,如果你想这样做,你最好重载operator[]这样的东西:

struct Point { 
    float x, y, z;

    float &operator[](size_t subscript) { 
        switch(subscript) {
            case 0: return x;
            case 1: return y;
            case 2: return z;
            default:  throw std::range_error("bad subscript");
        }
    }
};

这样,如果编译器在浮点数之间插入填充,它仍然可以工作 - 任何能够阅读C ++的人都应该能够毫无问题地理解它。

答案 2 :(得分:1)

这只是将成员数据视为数组的一种方法。您也可以使用结构来执行此操作。当您想要可读性但希望能够迭代简单的数据结构时,这非常有用。一个示例用法是以这种方式声明矩阵:

typedef struct {
   CGFloat m11,m12,m13,m14;
   CGFloat m21,m22,m23,m24;
   CGFloat m31,m32,m33,m34;
   CGFloat m41,m42,m43,m44;
} CATransform3D;

您可以方便地按名称引用每个单元格,但您也可以在任何地方传递指向m11的指针(C将结构视为数组,m11是第一个元素),并迭代所有元素。