需要从嵌套 class C++ 引用和更新值

Need to reference and update value from nested class C++

请耐心等待,我是 C++ 的新手。我正在尝试更新存储在向量中的值,但出现此错误:

 non-const lvalue reference to type 'Node'

我在 std::vector 周围使用了一个简单的包装器,因此我可以共享 contains 和其他方法(类似于 ArrayList 在 Java 中的方式)。

#include <vector>

using namespace std;

template <class T> class NewFrames {

public:

    // truncated ...

    bool contains(T data) {
        for(int i = 0; i < this->vec->size(); i++) {
            if(this->vec->at(i) == data) {
                return true;
            }
        }

        return false;
    }

    int indexOf(T data) {
        for(int i = 0; i < this->vec->size(); i++) {
            if(this->vec->at(i) == data) {
                return i;
            }
        }

        return -1;
    }

    T get(int index) {
        if(index > this->vec->size()) {
            throw std::out_of_range("Cannot get index that exceeds the capacity");
        }

        return this->vec->at(index);
    }

private:
    vector<T> *vec;

};

#endif // A2_NEWFRAMES_H

利用这个wrapper的class定义如下:

#include "Page.h"
#include "NewFrames.h"

class Algo {

private:
    typedef struct Node {
        unsigned reference:1;
        int data;
        unsigned long _time;

        Node() { }

        Node(int data) {
            this->data = data;
            this->reference = 0;
            this->_time = (unsigned long) time(NULL);
        }
    } Node;

    unsigned _faults;
    Page page;
    NewFrames<Node> *frames;
};

我现在需要引用矢量内的 Node 对象之一,但我需要能够将 reference 更改为不同的值。根据我在 SO 上的发现,我需要这样做:

const Node &n = this->frames->get(this->frames->indexOf(data));

我试过只使用:

Node n = this->frames->get(this->frames->indexOf(data));
n.reference = 1;

然后在调试器中查看数据,但稍后检查时值没有更新。考虑一下:

const int data = this->page.pages[i];
const bool contains = this->frames->contains(Node(data));
Node node = this->frames->get(index);
for(unsigned i = 0; i < this->page.pages.size(); i++) {
    if(node == NULL && !contains) {
        // add node
    } else if(contains) {
        Node n = this->frames->get(this->frames->indexOf(data));
        if(n.reference == 0) {
            n.reference = 1;
        } else {
            n.reference = 0;
        }
    } else {
        // do other stuff
    }
}

随着循环的后续传递,具有该特定数据值的节点会有所不同。

但如果我尝试更改 n.reference,我会收到错误消息,因为 const 阻止对象更改。有没有办法获取此节点以便更改它?我来自友好的 Java 世界,在那里类似的东西可以工作,但我想 know/understand 为什么这个 不能 在 C++ 中工作。

Node n = this->frames->get(this->frames->indexOf(data));
n.reference = 1;

这会从 frames 复制 Node 并将 copy 存储为对象 n。修改副本不会改变原始节点。

最简单的"fix"是使用引用。这意味着将 get 的 return 类型从 T 更改为 T&,并将前两行更改为

Node& n = this->frames->get(this->frames->indexOf(data));
n.reference = 1;

这应该能让代码正常工作。但是代码中有太多的间接性,很可能还有其他问题没有出现。正如@nwp 在评论中所说,使用 vector<T> 而不是 vector<T>* 将为您省去很多麻烦。

在我提供风格建议的同时,去掉那些 this->;他们只是噪音。并简化安全带有效性检查:当您从 0 循环到 vec.size() 时,您无需在访问元素时检查索引是否正常;将 vec.at(i) 更改为 vec[i]。在 get 中,请注意如果 index 超出范围,vec.at(index) 将抛出异常,因此您可以跳过初始范围检查或保留检查(在修复它之后,以便它检查实际范围)并再次使用 vec[index] 而不是 vec.at(index).