所以,我有这个包含另一个类的向量的类。每当我尝试将一个新对象推入此向量时,它每次都在同一个内存位置创建该对象。
(希望)相关代码:
class FSM{
private:
std::vector<Node> nodeList;
int cap;
int obs;
int topNode;
public:
FSM(int nodeCap, int numObs){
cap = nodeCap;
obs = numObs;
topNode = -1;
}
bool addNode(){
if (isFull()) return false;
nodeList.push_back(Node(obs));
topNode++;
return true;
}
现在,如果我在main函数中创建一个独立的Node对象并且cout&amp;节点,我会得到不同的内存位置。但是在FSM类中创建的那些总是相同的。此外,如果我更改了FSM类存储的其中一个节点中的任何内容,它会为所有节点更改它。我不知道发生了什么。
编辑:根据要求,这是Node类。只是要发布整个事情,不确定什么是相关的。
class Node{
private:
std::vector<int> connects;
int action;
public:
Node(int numObs){
for(int i = 0; i < numObs; i++){
connects.push_back(-1);
}
srand(time(NULL));
}
void setConnections(std::vector<int> newVec){
for (int i = 0; i < connects.size(); i++){
connects[i] = newVec[i];
}
}
int getConnection(int index){
return connects[index];
}
std::vector<int> getConnectionList(){
return connects;
}
void setAction(int act){
action = act;
}
int getAction(){
return action;
}
void setRandomConnections(int numNodes){
for (int i = 0; i < connects.size(); i++){
connects[i] = rand() % numNodes;
}
}
};
编辑第二个:这是我主要做的事情。
int main(){
FSM myFSM(5, 3);
while (!myFSM.isFull()){
myFSM.addNode();
std::cout << &myFSM.getTopNode(); // getTopNode() returns the most recent
// node.
}
}
答案 0 :(得分:4)
如果getTopNode执行了我认为的操作,那么您将打印临时对象的地址(也就是顶级节点的副本,而不是顶级节点本身)。所以代码没有意义。
Here我已经为FSM中节点的位置实现了打印功能:
void printNodeLocations()
{
for(Node& n : nodeList) { std::cout << &n << std::endl; }
}
我得到了不同的预期:
0x8ad3018
0x8ad301c
编辑:我无法再现您声称更改一个节点会更改所有节点。 See updated code
答案 1 :(得分:1)
这一行:
std::cout << &myFSM.getTopNode();
可能会打印临时对象的地址,而不是矢量中的实际对象。如果你不是通过引用而是通过值返回,那将是真的。
因此,如果每次都在同一位置创建临时值并不奇怪,因为在临时死亡之后,它在内存中的位置可以在以后再次使用。
为了获得实际的对象而不是它的副本,getTopNode()需要这样做:
Node& FSM::getTopNode()
{
if (nodeList.empty()) {
// Up to you how to handle this error.
}
return nodeList.back();
}
当然,如果你当前的getTopNode()实现实际上已经返回一个指针:
Node* FSM::getTopNode()
然后你的问题是你打印出指针的地址而不是指针本身。在这种情况下,您应该打印:
std::cout << myFSM.getTopNode();
答案 2 :(得分:0)
没有类似于你的事情。
#include <iostream>
#include <vector>
class Node{
private:
std::vector<int> connects;
int action;
public:
Node(int num){
for(int i = 0; i < num; i++){
connects.push_back(i);
}
}
std::vector<int> getConn()
{
return connects;
}
};
class FSM{
private:
std::vector<Node> nodeList;
public:
FSM(){}
void addNode(int size){
Node l(size);
std::cout<<"temp_address "<<&l<<"\n";
nodeList.push_back(l);//use of default copy constructor
}
void printList(){
std::vector<int> p;
for (int i=0; i<nodeList.size(); i++)
{
std::cout<<"Node_arr_num "<<i<<" mem_address "<<&nodeList[i]<<"\nConnections:";
p=nodeList[i].getConn();
for (int j=0; j<p.size(); j++)
std::cout<<" "<<p[j];
std::cout<<"\n";
}
}
};
int main()
{
FSM f;
f.addNode(5);
f.addNode(10);
f.addNode(3);
f.printList();
return 0;
}
temp_address 0xbfea7660
temp_address 0xbfea7660
temp_address 0xbfea7660
Node_arr_num 0 mem_address 0x8dab098
Connections: 0 1 2 3 4
Node_arr_num 1 mem_address 0x8dab0a8
Connections: 0 1 2 3 4 5 6 7 8 9
Node_arr_num 2 mem_address 0x8dab0b8
Connections: 0 1 2
当您的应用程序增长时,请小心添加节点。如果l
更复杂(包含具有动态分配内存的字段),则必须使用类Node(obs)
的显式复制构造函数复制临时Node
对象(您的Node
)。< / p>