按值传递容器还是按引用传递容器

6

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

假设有以下情况:

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

    int w;
    int h;
    uchar* data;
}

当传递该类的对象时,复制的仅是两个整数和指针而非全部数据。在这种情况下,是否有必要通过引用传递它?或者不通过引用传递它是否有目的?

引发这个问题的是我读到C++中迭代器被设计成轻量级并可以按值传递。所以,我认为这个概念可能适用于表示容器实际数据的类而非数据本身。


1
uchar* data 是什么?我的意思是它是一个深度复制和清理的资源吗? - Jarod42
2
默认的析构函数不会删除data,所以显然指针指向了类外部的资源。复制这样的指针可能是可以的。也许wh是指向数据的特定部分,类似于string_view - Bo Persson
3
如果那个类只是另外一个地方管理的内存的一个视图,你应该把它命名为“imageView”,以表明它仅仅代表对图像数据的视图,而不是代表图像数据本身。 - PeterT
@BoPersson 他称那个东西为“容器”。我认为我们可以同意,如果内存是在其他地方管理的,那么它基本上只是对该内存的视图,就像迭代器基本上是对容器的视图一样。但是人们通常不会将迭代器本身称为容器。 - PeterT
抱歉,这个例子可能有点糟糕。我只是需要一个最简单的例子来澄清我的想法。当然不是私有的。由于我将使用智能指针,所以不会出现内存泄漏问题。与问题无关的所有内容都将以某种方式解决。 - Humam Helfawi
显示剩余4条评论
2个回答

6

在我看来,如何传递参数的最佳指南可以在Herb Sutter的优秀演讲中找到,链接是Back to the Basics! Essentials of Modern C++ Style。在您的情况下,按值传递将是最佳选择,因为您的结构体很容易复制。

cpp parameter passing overview


你甚至可以认为这个结构体也很“便宜移动”,特别是如果它有一个像 unique_ptr 这样的托管指针,它保证支持正确的移动,并建议通过引用传入。我认为这个特定的例子是如此之小,以至于两个参数/决策都是同样有效的。 - CompuChip
重要的不仅是复制成本;独立的对象可以获得更多的优化机会,因为编译器可以假设没有其他东西可以指向/引用该对象。例如:` 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的值不会改变。 - Nevin

5
使用默认的拷贝构造函数,任何复制都将是浅层复制,不会复制由data指向的内存。因此,当您通过引用传递时,只会传递两个整数和指针,总共约12字节(取决于您的架构,即指针大小)。
那种差异非常小,无论您是按值传递还是按引用传递都没有太大关系。后者可能会更快一些,因为指针可能总是可以通过CPU寄存器传递,而12个字节则不一定,但这确实是微观优化。
个人而言,除了基本类型之外,我通常默认通过(const)引用传递任何东西,除非我有理由不这样做(请参见jupp0r's answer)。在开发过程中的主要优势是,随着类的增长,我不必担心它何时变得太大并更改所有函数以通过引用传递。
就默认的C++迭代器而言:请注意它们基本上是指针。事实上,我知道对于启用优化的Microsoft Visual C++ Release模式编译器来说,对于像std::vector这样的连续数据结构的迭代器将简化为指针。我不知道其他编译器是否也会这样做,但我认为应该会。但是,您会注意到,如果禁用了优化,则在循环增量中编写it++和++it之间突然存在差异-仅因为前一种情况中有额外的复制操作。因此,即使“复制成本低廉”,如果您经常这样做,也可能会产生影响。像往常一样:当担心性能时,请测量并根据数字做出决策。

除了连续的数据结构之外,任何其他类型的迭代器都不能简化为指针,因为它们具有不同的语义。 - Nevin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接