如何循环存储在地图中的对象矢量? C ++

时间:2016-09-04 00:29:24

标签: c++ vector iteration

我有一个带有矢量变量的函数类,它存储其他函数对象。每个函数都映射到网络类中。

std::map<std::string, Function> functions;

当我输出单个对象时,它会在映射函数后显示该对象的向量变量(next_func)。

cout << network.functions.at("C");

输出:

(FUNCTION: id=C, next_func=[D])

然而,当我尝试遍历地图以尝试显示每个映射函数的向量变量时,它会显示一个空的向量变量。

for (auto element : network.functions) {
    cout << element.second << "\n";
}

输出:

(FUNCTION: id=C, next_func=[])
(FUNCTION: id=D, next_func=[])
(FUNCTION: id=E, next_func=[])

我不确定这是否与我的类结构有关,或者我是否没有使用适当的迭代形式来完成我需要的工作。

如何遍历映射对象以显示/操作向量变量中的对象?

工作示例:

Function.h

#ifndef Function_H
#define Function_H

#include <vector>
#include <iterator>
#include <iostream>
#include <string>

using namespace std;

class Function {
public:
    string name;
    std::vector<Function*> func_pre;
    std::vector<Function*> func_next;
public:  
    Function();
    Function(const string& id, int duration);
    Function(const Function&);
    ~Function();
    Function& operator=(const Function& t);
    string name_() const;
    void addNext(Function& s);
    void addPre(Function& p);
    std::string toString() const;
    friend std::ostream& operator<<(std::ostream&, const Function&);
};
#endif

Function.cpp

#include <sstream>
#include "Function.h"

using namespace std;

Function::Function() {
    name = "";
}

Function::Function(const string& id, int duration) {
    this->name = id;
}

Function::Function(const Function& t) {
    this->name = t.name_();
}

Function::~Function() {}

Function& Function::operator=(const Function& t) {
    if (this != &t) {
        name = t.name;
    }
    return *this;
}

string Function::name_() const {
    return this->name;
}

void Function::addNext(Function& s) {
    Function* e = &s;
    func_next.push_back(e);
}

void Function::addPre(Function& p) {
    Function* e = &p;
    func_pre.push_back(e);
}

std::ostream& operator<<(std::ostream& s, const Function& e) {
    s << e.toString();
    return s;
}

std::string Function::toString() const {
    std::string s = "(Function: id=" + name +" ,to=";
    s = s+"[";
    for(unsigned int i = 0; i < func_next.size(); i++)
        s = s + func_next[i]->name_() + " ";
    s = s+"], from=[";
    for(unsigned int i = 0; i < func_pre.size(); i++)
        s = s + func_pre[i]->name_() + " ";
    s = s + "])";
    return s;
}

Map.h

#ifndef Map_H
#define Map_H

#include <map>
#include <vector>
#include <string>
#include "Function.h"

class Map{

public:
    std::map<std::string, Function> fucntions;
public:
    explicit Map();
    Map(const Map& n);
    ~Map();
    Map& operator=(const Map& i);
    void addFunction(const string id, int x);
    void addDep(const string& from, const string& to);
    std::string toString()const;
};
#endif

Map.cpp

#include "Map.h"
#include <iterator>
#include <iostream>
#include <iterator>

using namespace std;

Map::Map() {
    fucntions = {};
}

Map::Map(const Map& n) {
    this->fucntions = n.fucntions;
}

Map::~Map() {
}

Map& Map::operator=(const Map& i) {
    if (this != &i) {
        fucntions = i.fucntions;
    }
    return *this;
}

void Map::addFunction(const string id, int x) {
    Function t(id, x);
    fucntions[t.name_()] = t;
}

void Map::addDep(const string& from, const string& to) {
    fucntions.at(from).addNext(fucntions.at(to));
    fucntions.at(to).addPre(fucntions.at(from));
}

std::string Map::toString() const {
    std::string s = "(\n";
    std::map<std::string, Function>::const_iterator i = fucntions.begin();
    std::map<std::string, Function>::const_iterator end = fucntions.end();
    if (i == end)
        s += "<Empty>";
    else
        do{
            s += (*i).second.toString();
            if (++i != end) s+= ",\n";
        }while (!(i==end));
    s +="\n)";
    return s;
}

的main.cpp

#include <iostream>
#include "Map.h"
#include "Function.h"

using namespace std;

int main(){
    Map m;
    m.addFunction("A", 10);
    m.addFunction("B", 30);
    m.addFunction("C", 20);
    m.addFunction("D", 40);
    m.addFunction("E", 20);
    m.addDep("A", "B");
    m.addDep("A", "C");
    m.addDep("B", "D");
    m.addDep("D", "E");
    m.addDep("C", "E");
    m.addDep("B", "C");

    cout << m.fucntions.at("C") << "\n\n";

    for (auto& element : m.fucntions) {
        cout << "Predecessor counts: " << element.first
                << " : "<< element.second << "\n";
    }
}

2 个答案:

答案 0 :(得分:2)

此复制构造函数

Function::Function(const Function& t) {
    this->name = t.name_();
}

...使指针成员具有不确定的值。

使用一些编译器和选项,您可能会获得nullpointer值,但这不能保证:正式访问这些指针成员的值是Undefined Behavior。

此外,此复制赋值运算符

Function& Function::operator=(const Function& t) {
    if (this != &t) {
        name = t.name;
    }
    return *this;
}

...不指定指针成员。这在技术上是否是错误取决于您的逻辑。但它确实看起来像一个错误,因为它是一个不能保留完整赋值的赋值。

提示:您可以通过构造函数的成员初始化列表执行此操作,而不是通过赋值初始化成员,如下所示:

Function::Function( Function const& other )
    : name( other.name )
    , func_pre( other.func_pre )
    , func_next( other.func_next )
{}

这样做的好处是可以避免额外的默认初始化,它适用于不可分配但可复制的成员。

如果您没有定义或声明复制构造函数,那么这个特定的实现示例正是编译器为您生成的。

答案 1 :(得分:2)

在main.cpp中尝试以下代码

for (map<string,Function>::iterator element=m.fucntions.begin();element!=m.fucntions.end();element++) {
    cout <<"Predecessor counts: " <<  element->first << " : "<< element->second << "\n";
}

我获得的输出是

Predecessor counts: A : (Function: id=A ,to=[B C ], from=[])
Predecessor counts: B : (Function: id=B ,to=[D C ], from=[A ])
Predecessor counts: C : (Function: id=C ,to=[E ], from=[A B ])
Predecessor counts: D : (Function: id=D ,to=[E ], from=[B ])
Predecessor counts: E : (Function: id=E ,to=[], from=[D C ])

我已经实现了c ++ 98循环迭代器,我无法弄清楚for循环中的错误,但我想我的解决方案可以帮助你。