我如何处理这个C++;多重地图问题? 我是C++初学者,我在一个简单的程序上遇到了一个让我难堪的问题…基本上,我创建了一个多重映射,它接受字符串person name的一部分和指向person对象的指针
因此,我使用的第一个函数是“Add()”函数。我基本上是用名字和年龄构造一个新人,然后设置一个指向该对象的指针。然后我将名称和对象作为一对插入到多重映射中 运行find()函数时会出现问题。。。我的输出只给了我一个有效的名字,但对于我的年龄,我得到的似乎是一个截断的内存地址或一个随机数?因为我是一个初学者,我很确定我在做一些非常简单但非常愚蠢的事情。我认为您不需要运行代码,因为它非常简单。感谢所有的帮助。谢谢大家! 我的可运行文件:我如何处理这个C++;多重地图问题? 我是C++初学者,我在一个简单的程序上遇到了一个让我难堪的问题…基本上,我创建了一个多重映射,它接受字符串person name的一部分和指向person对象的指针,c++,c++11,pointers,C++,C++11,Pointers,因此,我使用的第一个函数是“Add()”函数。我基本上是用名字和年龄构造一个新人,然后设置一个指向该对象的指针。然后我将名称和对象作为一对插入到多重映射中 运行find()函数时会出现问题。。。我的输出只给了我一个有效的名字,但对于我的年龄,我得到的似乎是一个截断的内存地址或一个随机数?因为我是一个初学者,我很确定我在做一些非常简单但非常愚蠢的事情。我认为您不需要运行代码,因为它非常简单。感谢所有的帮助。谢谢大家! 我的可运行文件: #包括“Person.h” #包括 使用名称空间std; 多重
#包括“Person.h”
#包括
使用名称空间std;
多重地图;
迭代器计数器;
void add()
{
字符串名;
智力年龄;
姓名;
年龄;
人员生成人员(姓名、年龄);
//避免使用动态类指针进行内存优化。
//避免:Person*pointer=新的Person(姓名、年龄)。
Person*指针=&generatedPerson;
insert({name,pointer});
}
void find()
{
找到字符串;
找不到人;
for(counter=personMap.begin();counter!=personMap.end();counter++)
{
如果(计数器->第一个==personToBeFound)
{
大家好,@1201programalm的评论是绝对正确的,然而,我自己想,我该如何“拯救”这个程序(a)用最小的努力,(b)获得正确的版本,(c)非常接近原始版本
因此,这里有一个新的main.cc
版本(Person.h
,Person.cc
无需更改):
#包括“Person.h”
#包括
使用名称空间std;
多重地图;
迭代器计数器;
void add()
{
字符串名;
智力年龄;
姓名;
年龄;
插入({姓名,新人(姓名,年龄)});
}
void find()
{
找到字符串;
找不到人;
for(counter=personMap.begin();counter!=personMap.end();counter++)
{
如果(计数器->第一个==personToBeFound)
{
您是否正在地图中存储指向局部变量的指针,因此当您稍后尝试访问它时,指向的对象已被销毁(当add
返回时)从更高的层次来看,您可能应该在数据容器中存储值类型而不是指针,例如class Person
。映射将变成std::multimap。评论2:在std::vector
上使用std::multimap
的好处是,按键进行的搜索具有O(log(n))
time complexity。通过在映射上迭代,需要'O(n)`-explore std::multi_map::equal_range()@1201程序非常有帮助,但我想了解为什么会这样,以及未来如何解决此问题的最佳实践。从逻辑上讲,地图接受指向person对象的指针。为什么当我创建一个实际指针并指向person对象,然后将其输入地图时,它会断开?感谢您的帮助花点时间开始评论!我很感激!如果你能帮助的话,最好的做法是不要有一个指针容器。如果你不能避免指针,请使用std::unique\u ptr
notPerson*
。你的答案在fixed add()中是有意义的方法,谢谢你。请你解释一下为什么我不应该只删除键而不是值。如果我一路删除重复项也没关系。只删除键而不是将键的值置零不是很好吗?@michaow!精彩的回答和解释!非常感谢你花时间解释所有这些是@micha@XOR不客气,很高兴我能为你做些贡献。顺便说一句,你可能想回到这个人的演示,当它涉及到std::shared\u ptr
,std::unique\u ptr
时,这通常是C++11
中的方式。它在中包含。
#include "Person.h"
#include <map>
using namespace std;
multimap<string, Person*> personMap;
multimap<string, Person*>::iterator counter;
void add()
{
string name;
int age;
cout << "Please enter the name of the person: ", cin >> name;
cout << "Please enter the age of the person: ", cin >> age;
Person generatedPerson(name, age);
// Avoid dynamic class pointers for memory optimization.
// Avoided: Person* pointer = new Person(name, age).
Person *pointer = &generatedPerson;
personMap.insert({name, pointer});
}
void find()
{
string personToBeFound;
cout << "Who do you wish to find, friend: ", cin >> personToBeFound;
for (counter = personMap.begin(); counter != personMap.end(); counter++)
{
if (counter->first == personToBeFound)
{
cout << "\nName: " << counter->first << " Age: " << counter->second->getAge() << endl;
}
else if (counter->first != personToBeFound)
{
cout << "Error 404, person does not exist..." << endl;
}
}
}
// Experimental....
int main(int argc, char* argv[])
{
int menuChoice = -1;
while (menuChoice != 0)
{
cout << "\nPlease enter: "
"\n1 - to add a person "
"\n2 - to find a person"
"\n0 - to quit\n" << endl;
cin >> menuChoice;
switch(menuChoice)
{
case 1: add();
break;
case 2: find();
break;
case 0: menuChoice = 0;
}
}
}
#ifndef PERSON_H
#define PERSON_H
#include <string>
#include <vector>
#include <iostream>
class Person {
public:
// Constructors
/**
* Create a Person with the given name and age.
*
* @param name name of the person
* @param age age of the person - defaults to 0
*/
Person(const std::string& name, unsigned short age = 0);
// No explicit destructor necessary
// Mutators
/**
* Set the name attribute
*
* @param name name of the person
*/
void setName(const std::string& name);
/**
* Set the age attribute
*
* @param age age of the person
*/
void setAge(unsigned short age);
/**
* Increment the age attribute
*/
void growOlder();
/**
* Add a person to our list of children
*
* @param child Person to add as a child
*/
void addChild(const Person& child);
// Accessors
/**
* @return the Person's name
*/
const std::string& getName() const;
/**
* @return the Person's age
*/
unsigned short getAge() const;
/**
* @return a list of this Person's children
*/
const std::vector<const Person *>& getChildren() const;
/**
* Define the ostream's << operator as a friend of this class
* to allow this object to be printed to an output stream
*
* @param output the stream to print to
* @param p the Person to print
*
* @return the output stream printed to
*/
friend std::ostream& operator<< (std::ostream& output, const Person& p);
private:
// 0-arg Constructor
Person();
// Private attributes
std::string _name;
unsigned short _age;
std::vector<const Person *> _children;
}; // Person
#endif
#include "Person.h"
Person::Person(const std::string& name, unsigned short age) :
_name(name) , _age(age) {
}
void Person::setName(const std::string& name) {
_name = name;
}
void Person::setAge(unsigned short age) {
_age = age;
}
void Person::growOlder() {
_age++;
}
void Person::addChild(const Person& child) {
_children.push_back(&child);
}
const std::string& Person::getName() const {
return _name;
}
unsigned short Person::getAge() const {
return _age;
}
const std::vector<const Person *>& Person::getChildren() const {
return _children;
}
std::ostream& operator<< (std::ostream& output, const Person& aPerson) {
// Print our attributes to the output stream
return output << "Name: '" << aPerson._name << "', Age: " << aPerson._age;
}
#include "Person.h"
#include <map>
using namespace std;
multimap <string, Person *> personMap;
multimap <string, Person *>::iterator counter;
void add()
{
string name;
int age;
cout << "Please enter the name of the person: ", cin >> name;
cout << "Please enter the age of the person: ", cin >> age;
personMap.insert({ name, new Person(name, age) });
}
void find()
{
string personToBeFound;
cout << "Who do you wish to find, friend: ", cin >> personToBeFound;
for (counter = personMap.begin(); counter != personMap.end(); counter++)
{
if (counter->first == personToBeFound)
{
cout << "\nName: " << counter->first
<< " Age: " << counter->second->getAge() << endl;
}
else
{
cout << "Error 404, person does not exist..." << endl;
}
}
}
int main(int argc, char* argv[])
{
int menuChoice = -1;
while (menuChoice != 0)
{
cout << "\nPlease enter: "
"\n1 - to add a person "
"\n2 - to find a person"
"\n0 - to quit\n" << endl;
cin >> menuChoice;
switch(menuChoice)
{
case 1:
add();
break;
case 2:
find();
break;
case 0:
menuChoice = 0;
break;
}
}
// -- How to go about clearing the heap? --
for (counter = personMap.begin(); counter != personMap.end(); counter++)
{
if (counter->second) {
delete counter->second;
counter->second = nullptr;
}
}
}