在这种情况下的值或引用语义?

发布于 2024-10-07 09:06:22 字数 366 浏览 7 评论 0原文

我对在某些情况下是否选择值语义或引用语义没有感觉(但我希望如此)。有什么我可以应用的经验法则吗?

我通常会选择除内置数据类型(char、int、bool、double 等)以外的所有内容的引用。但是,有时无法从函数返回引用,因此我必须使用指针。下面的函数就是一个例子:

Foo bar()
{
    Foo f;
    f.do_stuff();
    return f;
}

我使用 boost::shared_ptr 来存储 Foo 对象,但它使得使用该对象变得非常难看。我目前正在研究一个返回双端队列的函数,该双端队列几乎不会超过 10 个元素(这是我的假设,我无法确定)。按值返回可以吗?我的考虑是否属于过早优化的情况?

I don't have a feeling (yet, I hope) for whether to chose value or reference semantics in some situations. Is there any rule of thumb I can apply?

I usually pick references for everything other than the built-in data types (char, int, bool, double etc.). However, sometimes it's not possible to return references from a function, so I would have to use pointers. The following function is an example of this:

Foo bar()
{
    Foo f;
    f.do_stuff();
    return f;
}

I'd use boost::shared_ptr to store the Foo object, but it makes working with the object quite ugly. I'm currently looking at a function that returns a deque that will hardly ever have more than 10 elements (that's what I assume, I have no way of making sure). Would it be OK to return this by value? Are my considerations a case of premature optimization?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

逆夏时光 2024-10-14 09:06:22

按值返回很好,因为大多数编译器都会优化额外的副本(这称为返回值优化,或者在您的情况下称为命名返回值优化)。

但惯用的方法是

void bar(Foo& out)
{
   out.do_stuff();
}

Returning by value is fine, since most compilers will optimize the extra copy away (this is called Return Value Optimization, or rather Named Return Value Optimization in your case).

But the idiomatic way is

void bar(Foo& out)
{
   out.do_stuff();
}
同展鸳鸯锦 2024-10-14 09:06:22

无论如何,不​​要通过引用或指针返回在堆栈上分配的任何内容(即局部变量,例如这里的 f)。

In any case, don't return anything allocated on the stack (i.e. local variable, such as f here) by reference or pointer.

酷遇一生 2024-10-14 09:06:22

您始终可以这样做:

Foo& bar(Foo& f)
{
    f.do_stuff();
    return f;
}

并像这样使用它:

Foo f;
bar(f);

这里的缺点是您无法保证 bar() 将收到 Foo 对象的新副本。如果这很重要,您必须将其修改为:

Foo& bar(Foo& f)
{
    f = Foo();
    f.do_stuff();
    return f;
}

但是,如果它确实获得了新副本,则会进行不必要的初始化。或者,您可以简单地在 doSomething() 之前检查 f,如果不符合预期则抛出异常。

You could always do this:

Foo& bar(Foo& f)
{
    f.do_stuff();
    return f;
}

And use it like this:

Foo f;
bar(f);

The drawback here is that you can't guarantee that bar() will receive a fresh copy of a Foo object. If that's important, you'll have to modify it to this:

Foo& bar(Foo& f)
{
    f = Foo();
    f.do_stuff();
    return f;
}

But then there will be an unnecessary initialization if it does get a fresh copy. Alternatively, you could simply examine f before doSomething() and throw an exception if it isn't up to expectations.

寂寞清仓 2024-10-14 09:06:22

当您想要维护任何变量或对象的状态时(即,在被调用例程对变量/对象完成一些处理后,将相同的变量返回到调用例程)以及将大数据传递给该功能否则将出现大容量数据的双重副本。

此外,在某些需要防止按位复制对象的情况下,在这种情况下,我们将类的复制构造函数设置为私有。

Use a reference when you want to maintain the state of any variable or object (i.e reurning the same variable to the calling routine after some procesisng has been done on the variable/object by the called routine) and also in case of passing large data to the function else there will be double copy of the large volumed data.

Also in some where copying of objects bit wise needs to be prevented, in such cases we make the copy constructor of a class as private.

以歌曲疗慰 2024-10-14 09:06:22

我的正常规则是:

  1. 始终使用按值传递。

    很简单吧?参考烂了。它们根本不应该被引入。

  2. 如果您有“类似数据结构的值”,请传递它。如果您有“类似对象的数据结构”,则传递指针(引用语义,按值传递)。

    通常很清楚类型是什么:值还是对象。如果你可以改变它,它就是一个对象。

My normal rules are:

  1. always use pass by value.

    Simple, eh? Reference suck. They should never have been introduced.

  2. If you have a "value like data structure" pass it. If you have an "object like data structure" pass a pointer (reference semantics, pass by value).

    It's usually clear what kind of thing a type is: value or object. If you can mutate it, its an object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文