代码之家  ›  专栏  ›  技术社区  ›  greatwolf Romowski

这个C++语法意味着什么,为什么它会起作用?

  •  15
  • greatwolf Romowski  · 技术社区  · 15 年前

    我在查看Opende的源代码时,在一个类上遇到了数组索引操作符“[]”的wierd语法用法。下面是一个简单的示例,用于显示语法:

    #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 回复  |  直到 14 年前
        1
  •  17
  •   rlbond    15 年前

    p 正在隐式转换为 const float* const ,哪个指向 x . 所以 *p X , *(p+1) y 等等。 这是一个相当奇怪的想法(而且令人困惑!)当然,这样做。通常情况下,最好将x、y和z存储在一个数组中,如果他们真的想这样做的话,还需要一个函数来获取整个数组。

        2
  •  8
  •   Jerry Coffin    15 年前

    这里的想法是通过下标或名称来访问点的成员。但是,如果你想这样做,你最好不要超载。 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++的人都应该能够毫无问题地理解它。

        3
  •  1
  •   Vasiliy Kulakov    15 年前

    这只是将成员数据视为数组的一种方法。您也可以使用结构来实现这一点。当您希望可读性,但又希望能够迭代简单的数据结构时,这是很有用的。一个示例用法是这样声明一个矩阵:

    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是第一个元素),并遍历所有元素。