c++ - vector 和 []-运算符重载

标签 c++ vector operator-overloading

我从 std::vector 继承了我的类。现在我想重载 []-operator。
当我尝试为我的 vector 分配一个新值时,例如v[0]=5, 我应该收到消息 OK

这是我的代码(我知道,这没有意义,我只是在玩):

#include<vector>
#include<iostream>
class Vec : public std::vector<int> {
public:
    int operator[](int);
};

int Vec::operator[](int i) {
    (*this)[i] = i;
    std::cout << "OK";
    return 123;
}

int main() {
    Vec v;
    v[0]=5;
}

不幸的是,我收到以下错误:

In member function ‘int Vec::operator[](int)’:
error: lvalue required as left operand of assignmen
In function ‘int main()’:
error: lvalue required as left operand of assignment

最佳答案

这个特殊错误是因为您没有返回左值,通常定义为可以出现在赋值左侧的东西,例如v [0] = 5;。正如其他答案中指出的那样,您有更多问题,但这是您遇到的错误消息 (a) 的具体问题。

重载索引运算符的正确规范是:

int& operator[] (const int nIndex);

如果您想将其视为左值,则必须返回对该项目的引用(以便对其进行修改)。下面的代码显示了一个修复,尽管在这个简化的例子中显然所有数组索引都映射到相同的值:

#include <vector>
#include <iostream>

class Vec : public std::vector<int> {
    public:
        int& operator[] (int);    // <-- note the '&'
    private:
        int xyzzy;
};

int& Vec::operator[] (int idx) {  // <-- note the '&'
    std::cout << "OK\n";
    return xyzzy;
}

int main () {
    Vec v;
    v[0] = 5;
    v[1] = 6;
    std::cout << v[22] << '\n';
    return 0;
}

这个的输出是:

OK
OK
OK
6

实际上,您不会将所有索引都映射到相同的值,上面的代码只是为了说明正确的函数签名。我懒得给出更完整的示例,因为使用非虚拟析构函数对类进行子类化通常会导致重要代码 (b) 出现问题。


(a) 通常认为将 std::vector 子类化不是一个好主意,因为析构函数不是虚拟的,因此在尝试时可能会遇到麻烦以多态方式销毁一个对象。

您最好使用has-a 关系(您的类包含 一个 vector )而不是is-a关系(您继承的地方)。

不幸的是,这意味着您可能必须创建很多从您的类到底层 vector 的传递方法(尽管只有您需要的方法),但这将解决析构函数的问题。


(b) 参见(a) :-)

关于c++ - vector 和 []-运算符重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16660437/

相关文章:

c++ - 通过继承重载运算符会导致歧义

c++ - 为什么我们需要在重载 >> 和 << 运算符时返回对 istream/ostream 的引用?

c++ - 在 C++ 中删除命名空间 boost

c++如何将文件解析为结构 vector

c++ - 使用shared_ptr而不是unique_ptr作为类成员只是为了避免隐式复制构造函数删除是否明智?

c++ - 类范围问题的 vector ?

c++ - 将卡片的 vector 传递给功能以打印和使用?

c++ - 返回类型不匹配(或不匹配)

c++ - opencv数组大于255

python - Ctypes:分配 double** ,将其传递给 C,然后在 Python 中使用