类在同一内存位置创建另一个类的多个对象(C++)
Class creating multiple objects of another class at the same memory location (C++)
所以,我得到了这个类,它包含另一个类的向量。每当我试图将一个新对象推入这个向量时,它每次都会在同一内存位置创建该对象。
(希望)相关代码:
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;
}
现在,如果我在主函数中创建一个独立的Node对象;节点,我得到不同的内存位置。但是在FSM类中创建的那些总是相同的。此外,如果我更改FSM类存储的某个节点中的任何内容,它会更改所有节点的内容。我不知道发生了什么事。
EDIT:根据要求,这是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.
}
}
如果getTopNode做了我认为它会做的事情,那么您将打印一个临时对象的地址(也就是顶部节点的副本,而不是顶部节点本身)。因此,该代码毫无意义。
在这里,我实现了FSM:中节点位置的打印功能
void printNodeLocations()
{
for(Node& n : nodeList) { std::cout << &n << std::endl; }
}
我得到了不同的预期:
0x8ad3018
0x8ad301c
编辑:我不能重复你的说法,即更改一个节点会更改所有节点。请参阅更新后的代码
此行:
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();
没有发生与您类似的事情。
#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
稍后添加节点时要小心,因为您的应用程序会增长。如果Node
更复杂(包含具有动态分配内存的字段),则必须使用类Node
的显式复制构造函数复制临时l
对象(或您的Node(obs)
)。
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- CMake-按正确顺序将项目与C运行时对象文件链接
- 空基优化子对象的地址
- 将对象数组的引用传递给函数
- 你能重载对象变量名本身返回的内容吗
- C++使用整数的压缩数组初始化对象
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 将对象移动到std::shared_ptr
- 代理对象的常量正确性
- 提升 ASIO 无法识别计时器对象
- 将Ref对象作为类成员
- 将包含C样式数组的对象初始化为成员变量(C++)
- 如何返回一个类的两个对象相加的结果
- 使用std::函数映射对象方法
- 是否需要删除包含对象的"pair"?
- 如何在自删除后将对象设置为nullptr
- 迭代时从向量和内存中删除对象
- 构造对象的歧义
- 使用"std::unordereded_map"映射到"std::list"对象