gpt4 book ai didi

c++ - 什么时候应该从类方法返回对对象的引用

转载 作者:可可西里 更新时间:2023-11-01 15:11:17 25 4
gpt4 key购买 nike

从类方法返回引用的最佳实践是什么。是不是你想在没有引用的情况下返回基本类型,而你想通过引用返回类对象。您推荐的任何文章、最佳实践文章。

最佳答案

我假设类方法是指成员函数。 “通过引用返回”是指“返回对成员数据的引用”。这主要与返回对本地的引用相反,这显然是错误的。

什么时候应该返回对成员数据的引用,什么时候返回数据本身?

默认情况下,您应该返回数据本身(又名“按值”)。这避免了返回引用的几个问题:

  • 用户存储引用并依赖于您的成员的生命周期,而不考虑包含对象(您的对象)将存在多长时间。导致悬挂指针。

  • 用户代码变得依赖于确切的返回类型。例如,您使用 vector<T>用于实现(这就是您的 getter 返回的内容)。出现类似“vector<T> foo = obj.getItems()”的用户代码。然后你改变你的实现(和 getter)来使用 deque<T> -- 用户代码中断。如果您一直按值返回,您可以简单地让 getter 创建一个本地 vector ,从成员双端队列复制数据,然后返回结果。对于小型收藏来说相当合理。 [*]

那么什么时候应该返回引用呢?

  • 当返回的对象很大(Image)或不可复制(boost::signal)时可以考虑。但是,与往常一样,您可以选择更面向对象的模式,让您的类 事情,而不是让事情卡在上面。在Image情况下,您可以提供 drawCircle成员函数,而不是返回 Image&并让您的用户在上面画一个圆圈。
  • 当您的数据在逻辑上归您的用户所有,而您只是为他保留这些数据时。考虑标准集合:vector<T>::operator[]返回对 T 的引用,因为这就是我想要得到的:我的确切对象,而不是它的拷贝。

[*] 有一种更好的方法来确保面向 future 的代码。而不是返回一个 vector (通过引用或按值)返回一对迭代器到你的 vector - 一个开始和结束一个。这让您的用户可以一切他们通常使用双端队列或 vector 进行的操作,但与实际实现无关。 Boost 提供 boost::iterator_pair以此目的。作为一项福利,它还重载了 operator[],因此您甚至可以执行“int i = obj.getItems()[5]”而不是“int i = obj.getItems().begin()[5]”。

此解决方案可推广到任何允许您以一般方式处理类型的情况。例如,如果您保留 Dog成员,但您的用户只需要知道它是 Animal (因为它们只调用 eat()sleep() ),返回一个 Animal 引用/指针指向你的狗的免费存储分配拷贝。然后,当您确定狗是弱者并且您确实需要狼来实现时,用户代码就不会中断。

这种信息隐藏的作用不仅仅是确保 future 的兼容性。它还有助于保持您的设计整洁。

关于c++ - 什么时候应该从类方法返回对对象的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/494756/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com