首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C++中仅使用堆栈的后果

在C++中仅使用堆栈的后果
EN

Stack Overflow用户
提问于 2010-09-12 22:15:33
回答 12查看 1.9K关注 0票数 17

假设我认识一个刚接触C++的人。他不传递指针(这是正确的),但他拒绝通过引用传递。他总是使用按值传递。原因是他觉得“通过引用传递对象是设计失败的标志”。

该程序是一个小的图形程序,所讨论的大多数传递都是数学向量(3元组)对象。有一些大的控制器对象,但没有比这更复杂的了。

我发现很难找到一个致命的论点来反对只使用堆栈。

我会争辩说,传递值对于像向量这样的小对象是很好的,但即使这样,代码中也会发生许多不必要的复制。通过值传递大对象显然是浪费的,而且在功能上很可能不是您想要的。

有利的一面是,我认为堆栈在分配/释放内存方面速度更快,并且具有恒定的分配时间。

我能想到的唯一的主要论点是堆栈可能溢出,但我猜这不太可能发生?是否有其他参数反对只使用stack/pass by值,而不是通过引用传递?

EN

回答 12

Stack Overflow用户

回答已采纳

发布于 2010-09-12 23:02:06

子类型-多态性是一种通过值传递不起作用的情况,因为您会将派生类分割为它的基类。也许对某些人来说,使用子类型多态性是糟糕的设计?

票数 14
EN

Stack Overflow用户

发布于 2010-09-12 23:07:24

你朋友的问题与其说是他的想法,不如说是他的宗教信仰。给定任何函数,总是要考虑通过值、引用、常量引用、指针或智能指针传递的优缺点。那就决定吧。

我在这里看到的唯一破坏设计的迹象就是你朋友盲目的信仰。

这就是说,有一些签名并没有带来太多的东西。通过值获取const可能是愚蠢的,因为如果您承诺不更改对象,那么您可能也不会创建自己的副本。当然,除非它是一个原语,在这种情况下,编译器仍然可以智能地接受引用。或者,有时将指向指针的指针作为参数是很笨拙的。这增加了复杂性;相反,您可以通过引用指针来摆脱它,并获得相同的效果。

但不要一成不变地接受这些指导方针;永远要考虑你的选择,因为没有正式的证据可以消除任何选择的有用性。

  1. 如果您需要根据自己的需要更改参数,但又不想影响客户端,则按值获取参数。
  2. 如果要为客户端提供服务,并且客户端与服务的关系不是很密切,则考虑通过引用获取参数。
  3. 如果客户端与服务密切相关,则考虑不采用参数,而是编写成员函数。
  4. 如果希望为与服务密切相关但彼此非常不同的客户端族编写服务函数,则考虑采用引用参数。
  5. 也许可以让这个函数成为需要这种友谊的客户的朋友。如果您根本不需要更改客户端,那么可以考虑使用const-reference.

票数 7
EN

Stack Overflow用户

发布于 2010-09-13 00:45:09

我认为这个问题本身存在很大的误解。

堆栈或堆分配的对象与通过值、引用或指针传递的对象之间没有关系。

堆栈与堆分配

在可能的情况下,总是首选堆栈,然后为您管理对象的生命周期,这会更容易处理。

但在几种情况下,这可能是不可能的:

  • 虚拟构造(考虑Factory)
  • Shared所有权(尽管您应该总是尽量避免它)

我可能会错过一些,但在这种情况下,您应该使用SBRM (Scope Bound Resources Management)来利用堆栈生存期管理功能,例如通过使用智能指针。

传递方式:值、引用、指针

首先,语义是有区别的

空引用值,常量引用:传递的对象不会被method

  • reference:修改传递的对象可能会被method

  • pointer/const指针修改:与
  • 相同(对于行为),但可能为空

请注意,一些语言(函数式语言,如Haskell)在默认情况下不提供引用/指针。这些值一旦创建就是不可变的。除了一些处理外部环境的变通方法外,它们不会受到这种使用的限制,而且它以某种方式使调试变得更容易。

你的朋友应该知道,按引用传递或按指针传递绝对没有错:例如swap,它不能通过值传递来实现。

最后,多态不允许按值传递语义。

现在,让我们来谈谈表演。

通常情况下,内置函数应该通过值传递(避免间接传递),用户定义的大类应该通过引用/指针传递(避免复制)。事实上,大通常意味着复制构造函数不是微不足道的。

然而,有一个关于小型用户定义类的悬而未决的问题。最近发表的一些文章表明,在某些情况下,按值传递可能会让编译器进行更好的优化,例如,在这种情况下:

代码语言:javascript
复制
Object foo(Object d) { d.bar(); return d; }

int main(int argc, char* argv[])
{
  Object o;
  o = foo(o);
  return 0;
}

在这里,聪明的编译器能够确定o可以在不进行任何复制的情况下就地修改!(我认为函数定义必须是可见的,我不知道链接时间优化是否能解决这个问题)

因此,像往常一样,性能问题只有一种可能:度量

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3695147

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档