类在同一内存位置创建另一个类的多个对象(C++)

Class creating multiple objects of another class at the same memory location (C++)

本文关键字:对象 C++ 另一个 内存 位置 创建      更新时间:2023-10-16

所以,我得到了这个类,它包含另一个类的向量。每当我试图将一个新对象推入这个向量时,它每次都会在同一内存位置创建该对象。

(希望)相关代码:

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))。