按值或引用传递容器

Passing containers by value or by reference

提问人:Humam Helfawi 提问时间:1/27/2016 最后编辑:Humam Helfawi 更新时间:1/28/2016 访问量:3596

问:

我知道在一般情况下按值传递、引用或指针之间的区别。但是,我的问题是关于结构简单的容器的特殊情况。

假设这种情况:

class image{
    image()=default;
    image(image const&)=default;
    ~image()=default;

    int w;
    int h;
    uchar* data;
}

当传递此类的对象时,复制的只是两个整数和指针,而不是整个数据。在这种情况下,通过引用传递它有什么目的吗?还是不通过引用传递它有什么目的?

引发这个问题的原因是,我读到C++被设计为轻量级并按值传递。所以,我认为这个概念可以应用于表示实际数据而不是数据的容器的类。iterators

C++ C++11 按引用传递

评论

1赞 Jarod42 1/27/2016
什么?我的意思是,它是深度复制和清理的资源吗?uchar* data
0赞 Humam Helfawi 1/27/2016
复制(而不是克隆)时,只会复制指针,并且两个对象将共享相同的实际数据
0赞 Giorgi Moniava 1/27/2016
相关新闻: stackoverflow.com/questions/4172722/what-is-the-rule-of-three
2赞 Bo Persson 1/27/2016
默认析构函数不会删除 ,因此显然指针指向某些外部(类)资源。复制这样的指针是完全可以的。也许和指的是指向数据的某些特定部分,类似于一个?datawhstring_view
3赞 PeterT 1/27/2016
如果该类只是在其他地方管理的内存上的视图,您可能应该将其称为“imageView”,以表明它只是表示图像数据的视图,而不是表示图像数据本身。

答:

6赞 jupp0r 1/27/2016 #1

恕我直言,关于如何传递论点的最佳指南可以在 Herb Sutters 的精彩演讲《回归基础》中找到!现代C++风格的要点。在您的特定情况下,按值传递将是最佳选择,因为您的结构复制成本很低。

cpp parameter passing overview.

评论

0赞 CompuChip 1/27/2016
你甚至可以争辩说,这个结构也是“廉价的移动”——特别是如果它有一个托管指针,比如保证正确支持移动,并建议通过引用传递它。我认为这个特定的例子是如此之小,以至于两个论点/决定都同样有效。unique_ptr
0赞 Nevin 1/27/2016
重要的不仅仅是复制成本;不同的对象可以获得更多的优化机会,因为编译器可以假设没有其他对象可以指向/引用该对象。例如: ' int gi;int val(int i) { gi += i; gi += i; return i; } int ref(const int& i) { gi += i; gi += i; return i; } int main() { gi = 2; std::cout << val(gi) << std::endl; // 输出 2 gi = 2; std::cout << ref(gi) << std::endl; // 输出 8 } ' 在 ref() 中,编译器不能假设 i 的值不会改变。
5赞 CompuChip 1/27/2016 #2

使用默认的复制构造函数时,任何副本都是浅层的,并且不会复制 指向的内存。因此,当您通过引用传递时,将只传递两个整数和指针,总共大约12个字节(取决于您的体系结构,指针大小)。data

这种差异是如此之小,以至于你是按值还是按引用传递它并不重要。后者可能稍微快一些,因为指针可能总是可以通过 CPU 寄存器传入,而 12 字节可能不会,但这确实是微优化。

就我个人而言,默认情况下,我通过()引用传递除原始类型之外的任何东西,除非我有理由不这样做(参见jupp0r的答案)。开发过程中的主要优点是,随着类的增长,我不必担心它何时变得太大,也不必担心我的所有函数都可以通过引用传递。const

As far as the default C++ iterators go: note that they are meant to basically be just pointers. In fact I know that for Microsoft Visual C++ compiling in Release mode with optimizations enabled, iterators for contiguous data structures such as will reduce to just that. I am not aware if other compilers do this as well, I would think so. However you will notice that if you disable optimizations, then suddenly there is a difference between writing and in loop increments, for example - purely because of the additional copy operation in the former case. So even "cheap to copy" may have an impact if you do it often enough. As usual: when worried about performance, measure and decide based on the numbers.std::vectorit++++it

评论

0赞 Nevin 1/27/2016
Iterators for anything other than contiguous data structures cannot reduce to just pointers, as they have different semantics.