为啥当我尝试打印地图内容时,我得到的是地址而不是值?在 C++ 中

Posted

技术标签:

【中文标题】为啥当我尝试打印地图内容时,我得到的是地址而不是值?在 C++ 中【英文标题】:Why when i try to print a map content i get the adresses not the value ? in c++为什么当我尝试打印地图内容时,我得到的是地址而不是值?在 C++ 中 【发布时间】:2020-05-19 18:57:56 【问题描述】:

我有一个类 Servicii 是空的,还有 2 个类 CarBook(我稍后将用于租用更多类型的服务)扩展这个类。我还有另一堂课 Person 。 之后我声明了一个地图std::map<Person*,Servicii*> servicii; 和这个函数:

template<class T>
void rentService(Person *p,T service)

    if (typeid(*service).name() == typeid(Car).name()) 
        if(p->checkDriverLicense()==true)
        
            std::cout<<"Name:"<<p->getName()<<std::endl;
            servicii.insert(std::make_pair(p,service));
        
    

在 main 我创建了一些对象:

 Car *c1=new Car("Skoda",150,true,"red",2014);
 Person *p1=new Person("Ale",22);
 rentService(p1,c1);
    print(servicii);

和打印功能:

void print(std::map<Person*,Servicii*> m) 
    for(auto const &it: m) 
        std::cout << "[" << it.first << "," << it.second << "]" << std::endl;
    

当我编译时这是打印出来的:

Name:Ale
[0x1ba840,0x1ba4b8]

为什么我在地图上有地址?

【问题讨论】:

因为指针是-内存中的地址。 您有一张Person*Servicii* 的地图。换句话说,你有一个指针映射。如果你想看到名字,你需要做it.first-&gt;getName(),类似于你在rentService()做的事情。您期望/想要打印什么? 我有rentService(p1,c1)所以在rentService中p1是p,c1是T。所以如果p有驾照,把这个人(p1)和他租的车(c1)插入地图。 旁注:void print(std::map&lt;Person*,Servicii*&gt; m) 最好是void print(const std::map&lt;Person*,Servicii*&gt;&amp; m),以避免在打印之前复制整个地图。 【参考方案1】:

为什么我在地图上有地址???

因为这是您存储在地图中的内容。您为键和值指定的类型分别为Person*Servicii*。这两种类型都是指针。指针存储一个内存地址。

当你在字符流中插入一个指针时,它会被打印为一个十六进制数(指向char的指针除外,它的处理方式不同)。

Car *c1=new Car("Skoda",150,true,"red",2014);

不要使用裸拥有的指针。要么使用智能指针,要么存储为容器的元素。例如在这种情况下,std::map&lt;Person,Servicii&gt; 可能是合适的。

【讨论】:

旁注:在map 中使用指针作为键几乎从来都不是正确的做法,因为您没有映射到Person 您正在映射到Person 的位置是。你能想象那会是怎样的乐趣吗?一个人去商店取车,然后被告知:“不,史密斯先生。我们不能给你你的车,因为你站在离你还车的地方左边两英尺的地方。”然后机械师把你的车交给约翰斯顿先生,因为约翰斯顿站在正确的位置。【参考方案2】:

您需要取消引用指针:

void print(std::map<Person*,Servicii*> m) 
    for(auto const &it: m) 
        std::cout << "[" << *(it.first) << "," << *(it.second) << "]" << std::endl;
    

确保您已经为PersonServivii 实现了operator&lt;&lt;

【讨论】:

【参考方案3】:

您正在打印指针本身,它是一个地址。 你需要的是取消引用指针。 例如:

std::cout << it.first->getName() << "\n";

【讨论】:

【参考方案4】:

直接回答:

由于您的地图的键值对是指针,而指针是指向地址的地址,所以当您打印指针时,您会得到一个表示指针地址的十六进制值

推荐:

如果要打印自定义信息,可以为每个类重载
class Person 
public:
  ostream& operator<<(ostream& os, Person const& person) 
      return os << "I am " << person.m_name << " " << person.m_surname << endl;
  

private:
  string m_name;
  string m_surname;
;

如果您存储相对较小的对象(您需要根据硬件和软件要求做出决定),只需在映射中存储对象而不是指针。

易于维护的指针方式是智能指针,因此请尝试使用它们来代替原始指针。

【讨论】:

成员函数ostream&amp; operator&lt;&lt;(ostream&amp; os) 可以编写(给定Person p)类似p &lt;&lt; std::cout; 但不是std::cout &lt;&lt; p; 之类的东西,这是人们和标准库算法所期望的。流出的Person 也应该是const 按预期更改。谢谢! 不客气!它需要一个 friend 函数才能工作。

以上是关于为啥当我尝试打印地图内容时,我得到的是地址而不是值?在 C++ 中的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在使用该值时得到一个 nil 值,但当我打印它时它显示为 none nil?

为啥代码打印所有第一个索引?

为啥我得到的是 Apache2 欢迎页面而不是 laravel 页面?

为啥当我尝试获取我的 MAC 地址时得到一个空字符串?

为啥 termcolor 在 Windows 控制台中输出控制字符而不是彩色文本?

为啥我在尝试保存时得到黑色矩形而不是我的位图