【问题标题】:Copying from map to a list of pointers从地图复制到指针列表
【发布时间】:2018-10-11 01:54:23
【问题描述】:

我有一个有趣的任务,我有一个 std::mapCTurist(上一课)和 unsigned 变量。代码如下:

class CTurist
{
protected:
    string tName;
    int age;

public:
    CTurist() {};

    CTurist(string name, int age2)
    {
        tName = name;
        age = age2;
    }


    bool operator<(const CTurist& e) const
    {
        return age < e.age;
    }

    friend ostream& operator<<(ostream& os, const CTurist&& e);
    friend ifstream& operator>>(ifstream& is, CTurist&& e);
};

class CHotel:public CTurist
{
protected:

    string hName;
    int stars;
    int beds;
    map<CTurist, unsigned> Turisti;

public:
    unsigned Sum = 0;

    CHotel(){};

    CHotel(string hName2, int zvezdi, int legla)
    {
        hName = hName;
        stars = zvezdi;
        beds = legla;
    }



    int Compare()
    {
        list<CTurist*> list;

        int br=0;
        CTurist vyzrast;
        map<CTurist, unsigned>::iterator it = Turisti.begin();
        while (it != Turisti.end())
        {
            if (it->first < vyzrast)
            {
                br++;
            }
            else
            {
                list.push_back(std::move(&it->first));
            }
        }
    }
};

我知道这很长,但我认为最好把所有信息都告诉你。

现在,底部的int Compare() 函数是给我带来问题的函数。

我必须检查游客的年龄是否高于或低于我在这里称为vyzrast 的参数。我们正在比较age。如果它在下面,那就很简单了。

如果它在上面,我必须将这些游客添加到list&lt;CTurist*&gt;,又名。指向指针列表。如果我从对象而不是指针创建列表。运气不好,因此我在这里寻找如何解决它的建议。

【问题讨论】:

  • “我知道它很长,但我认为最好给你所有的信息”——你说得对,这确实是不必要的长。请创建一个更短的示例(只是重现问题的最低限度)。这样做的时候你可能会发现你需要做什么;-)
  • @YePhIcK:缩短。
  • 不清楚您为什么要从CTourist 导出CHotel,而您的酒店中存储有游客列表?至于关于指针的具体问题:指针必须 point 指向某物(在您的情况下为对象)。你不能只拥有没有它们指向的对象的指针。
  • list 应该包含什么?指向年龄小于 vyzrastCTursits 的指针?
  • @YePhIcK 这与以前不同。感谢您的关注。根据你所说的,我做了这个: CTurist* baba = new CTurist(it->first); list.push_back(std::move(baba));

标签: c++ stdmap stdlist


【解决方案1】:

您为什么对operator 重载使用右值引用?您应该使用const CTurist &amp; 来表示operator&lt;&lt;CTurist&amp; 来表示operator&gt;&gt;。你应该使用std::istream 代替operator&gt;&gt;

friend ostream& operator<<(ostream& os, const CTurist &e);
friend istream& operator>>(istream& is, CTurist &e);

除此之外,Compare() 在填充std::list 时根本没有理由使用std::move(),因为它是添加指针,而不是移动实际对象。

Compare() 不正确有几个原因:

  1. it-&gt;first 是一个实际的const CTurist 对象,但您的std::list 期待CTurist* 指针。 std::map 键是 const,所以 &amp;it-&gt;firstCTurist const * 指针(指向 const 对象的非 const 指针),而不是像您期望的 CTurist* 指针(指向非 const 对象的非 const 指针) .

  2. 您的 vyzrast 对象未初始化。您根本没有为其age(和tName)成员分配任何值,因此您的比较结果是不确定的。

  3. 您不会在每次循环迭代时递增您的 it 迭代器,因此如果 std::map 不为空,您将陷入无限循环。

试试类似的方法:

int Compare()
{
    std::list<const CTurist *> clist;

    int br = 0;
    CTurist vyzrast("", SomeAgeValueHere);

    std::map<CTurist, unsigned>::iterator it = Turisti.begin();
    while (it != Turisti.end())
    {
        if (it->first < vyzrast)
        {
            br++;
        }
        else
        {
            clist.push_back(&it->first);
        }
        ++it;
    }

    // use clist as needed...

    return SomeValueHere;
}

Live Demo

【讨论】:

  • 还值得一提的是,使用裸指针是一个糟糕的想法,尤其是对于新手而言。而且从来没有有充分的理由拥有受保护的数据成员(受保护的成员函数非常好用)
  • 非常感谢。很明显,我只是这门语言的新手,这种帮助非常有帮助。就像将来的参考一样,如果我想使用 list 而不是 const,我该怎么做?指针与列表和映射相结合对我来说真的是暗物质。
  • @TimothyY 使用const 有什么问题?这就是map 实际存储的内容,因此指向其键的指针需要匹配。否则,您可以 const_cast const 离开,但这不是一个好主意。
  • @RemyLebeau,抱歉回复晚了。不,没有错,我只是想看看是否有这样做的选项,你确实解释了。再次感谢。
猜你喜欢
  • 2011-04-09
  • 1970-01-01
  • 2020-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-15
  • 2020-02-26
相关资源
最近更新 更多