需要从嵌套 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)
.
请耐心等待,我是 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)
.