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

时间:2013-08-02 19:02:02

标签: 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;
        }

现在,如果我在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.
}
}

3 个答案:

答案 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;
}

Result:

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>