【问题标题】:Definition of operators运算符的定义
【发布时间】:2013-04-14 12:09:06
【问题描述】:

我正在尝试定义一些运算符。

我是按照这个文档做的:

http://courses.cms.caltech.edu/cs11/material/cpp/donnie/cpp-ops.html

是否存在需要定义两次的运算符?

我认为是索引运算符。我对吗?我将其定义为:

int operator [] (const int power) const{
    // here there is some code
}

假设我正确地实现了它,那么应该定义两次的运算符呢?

它支持接下来的事情吗?

a[1] = 3;
cout << a[1]; // I defined the << operator

任何帮助表示赞赏!

【问题讨论】:

  • 第二个可以工作,但第一个会失败,因为您没有返回参考。
  • 所以我必须定义它: int& operator[] (const int power) const;
  • 是的,你应该定义另一个返回int&amp;的运算符重载。
  • @0x499602D2 好的,谢谢
  • 请注意建议您应该定义另一个返回 int& 的运算符的重载 - 返回引用的版本不应该在函数参数列表之后有 const .

标签: c++ class operators


【解决方案1】:

我认为是索引运算符。我说的对吗?

几乎。它被称为下标运算符,它必须接受一个单个参数。您的操作员接受两个,这使您的代码非法。

它支持接下来的事情吗?

假设您有一个正确编写的operator [](在不知道您的应用程序逻辑的一些上下文的情况下,我不知道如何编写),那么您提到的两个指令都应该得到支持。

但是,为了做到这一点:

a[1] = 3;

为了合法(如果返回基本类型),operator [] 应该返回一个左值引用 - 因此,int&amp; 而不是int。当然,这意味着左值引用所绑定的对象不能是本地对象或临时对象,因为这意味着返回一个悬空引用。

int& operator [] (const int power) { // <== The function cannot be "const" if you
// ^                                 //     are returning a non-const lvalue ref
                                     //     to a data member or element of a data
                                     //     member array
    // here there is some code
}

您可能还需要const 版本的下标运算符:

int operator [] (const int power) const {
// No need to use a int const&    ^^^^^
// here, that is basically the    This member function can be const, since it is
// same as returning an int by    neither modifying the object on which it is
// value                          invoked, nor returns any non-const lvalue ref
                                  to a data member or an element of data member
    // here there is some code
}

【讨论】:

    【解决方案2】:

    您可能希望同时拥有const 和非const 版本的运算符:

    int operator[](int index) const { ... }
    int& operator[](int index) { ... }
    

    这将允许您的示例中给出的两种用法。即使aconst,它也将允许第二次使用。

    【讨论】:

    • @AlonShmiel:他们不这样做。第一个返回一个 int 值,该值可能是从对象内该索引处的值复制而来,但该副本与容器没有持续连接。第二个通常授予调用代码读/写访问被认为位于对象内该索引处的 int 值的权限 - 调用代码可以写入此x[i] = n; 并且更改会影响对象本身中的数据。只有当对象不是 const 时才调用第二个,以防止修改 const 对象。
    【解决方案3】:

    为了支持分配,有两个选项

    1. 索引运算符[] 返回一个引用
    2. 索引运算符[]返回一个实现赋值的代理对象

    第一种情况是最简单的,但不允许您区分读取和写入操作。第二种方法稍微复杂一些,但允许更多的控制:

    方法(2)的一个例子如下

    struct MyArray {
        std::vector<int> v;
    
        MyArray(int n) : v(n) {}
    
        struct ItemRef {
            MyArray& a;
            int index;
    
            ItemRef(MyArray& a, int index)
              : a(a), index(index)
            {}
    
            int operator=(int x) {
                printf("Writing to element %i\n", index);
                a.v[index] = x;
                return x;
            }
    
            operator int() {
                printf("Reading element %i\n", index);
                return a.v[index];
            }
        };
    
        ItemRef operator[](int index) {
            if (index < 0 || index >= int(v.size()))
                throw std::runtime_error("Invalid index");
            return ItemRef(*this, index);
        };
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-11
      • 2013-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-06
      • 2020-10-10
      • 2016-05-10
      相关资源
      最近更新 更多