【问题标题】: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),以避免在打印之前复制整个地图。

标签: c++ class dictionary object


【解决方案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 函数才能工作。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多