2

我有一个会议清单:

std::list<meeting*> meetings;

我想迭代列表并返回对特定会议的引用:

meeting& day::findMeeting( float StartHour )
{
std::list<meeting*>::iterator it;
for(it = meetings.begin(); it != meetings.end(); it++)
{
    if (it->getStartHour() == StartHour)
    {
        return *it;
    }
}
throw no_such_meeting_error;
}  

我收到以下错误:

  1. 'getStartHour' : is not a member of 'std::_List_iterator<_Mylist>'
  2. 'return' : cannot convert from 'meeting *' to 'meeting &'
  3. invalid return type 'meeting **' for overloaded 'operator ->'

我仍在学习 C++,所以很高兴了解我做错了什么。还,

  • 从函数返回对对象的引用是一种好习惯吗?有什么更好的办法吗?
  • 由于列表中项目的更改,引用是否可能会因某些原因而失效?

谢谢

4

6 回答 6

13

我有一份会议清单。

不,你没有。你有一个会议指针列表。从那个误解中,您所有的进一步错误都会流淌。

if (it->getStartHour() == StartHour)

如果您有会议列表,则此代码将是正确的。如果你有一个会议指针列表,那就错了。尝试:

if ((*it)->getStartHour() == StartHour)

下一个:

return *it;

尝试:

return **it;


或者,也许你真的想要一个“会议列表”。在这种情况下,您将这样声明您的列表:

std::list<meeting> meetings;

我不知道你想要哪个——会议列表或会议指南列表。这与程序其余部分的设计有关。我几乎从不保留一个装满指针的容器。

您可能需要一个指针列表,例如,如果您需要多个列表条目来引用同一个会议。(“我在 10 点与 Abe 会面,在 11 点与 Bob 和 Chuck 会面,然后在 10 点与 Abe 再次会面”?)

如果复制 ameeting是不可能的或过于昂贵,您可能还需要一个指针列表。在这种情况下,我建议您使用智能指针而不是裸指针。

要回答您的另一个问题,是的,返回对对象的引用是一件好事。您确实需要了解该对象的生命周期;在对象被销毁后,永远不要通过其引用访问该对象。

于 2012-05-15T16:05:47.923 回答
6

当它是指向您的对象 meeting 的指针时,您必须返回 **it 。返回一个参考很好,但要注意你以后用它做什么。指针的工作方式是,如果您编辑参考,列表中的项目也会更改,反之亦然。

于 2012-05-15T16:05:37.463 回答
4

你有std::list<meeting*>::iterator,但你的函数承诺返回meeting&

当您说*it这是要求迭代器给您它“指向”的内容时,在这种情况下将是meeting*静止的。因此,您还需要取消引用它以获得实际会议,例如:

return **it; 
于 2012-05-15T16:03:12.473 回答
3

综上所述,我建议您声明:

std::list<meeting> meetings;

代替:

std::list<meeting*> meetings;

(相应地将迭代器更改itstd::list<meeting>::iterator;),并让std::list容器为您完成所有与内存相关的工作,除非您出于某种原因特别想自己做。

关于返回参考,答案取决于您的需求。如果要将整个对象返回给调用函数,返回引用是个好主意。

const meeting& day::findMeeting(float startHour)此外,如果您希望返回的对象是只读的,调用函数能够访问该对象但不能更改它,请考虑使用 const-reference, 。

于 2012-05-15T16:13:03.853 回答
1

这与您的问题没有直接关系,但是在比较浮点数是否相等时应该小心。浮点数不准确,将它们与 == 进行比较是不安全的。

看看http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm

于 2012-05-15T16:20:19.423 回答
1

评论多于答案,但太大而无法发表评论。

如声明的那样,不能在给定const day&引用的情况下调用该函数。你可以考虑解决这个问题。

如果修改 a 的行为Meeting也是对 的修改,则day重载函数:

class day {
public:
  Meeting& findMeeting(float StartHour);
  const Meeting& findMeeting(float StartHour) const;
  //...
};

这两个定义看起来基本相同,除了第二个需要const_iterator. 现在findMeeting在 a 上调​​用时const day&将返回 a const Meeting&,或者如果在 a上调​​用day&仍将返回一个 modifiable Meeting

或者 -

如果修改 aMeeting不修改day,则只允许以任何一种方式调用该函数并始终返回一个 modifiable Meeting

class day {
public:
  Meeting& findMeeting(float StartHour) const;
  //...
};

或者 -

如果类的用户day根本不能修改它Meetings,做同样的事情但总是返回一个const Meeting&

class day {
public:
  const Meeting& findMeeting(float StartHour) const;
  //...
};

现在只允许class day方法(和friends)修改Meeting属于 a 的 s day。您可能还需要另一种private方法来查找可修改的会议,但在这种情况下,它应该具有不同的名称,而不是重载。

于 2012-05-15T16:17:07.010 回答