【问题标题】:Is passing by reference the right solution?通过引用传递是正确的解决方案吗?
【发布时间】:2021-07-29 08:07:45
【问题描述】:

我有这样的类型:

#pragma once

#include <stdio.h>
#include <string>

struct Color {
    std::string value;
};

struct Shirt {
    std::string brand;
    Color color;
};

class Outfit {
public:
    Outfit(Shirt shirt):
        shirt(shirt) {}

private:
    Shirt shirt;
};

我之前在此主题上查看了 this Stackoverflow 线程。

让我解释一下我的想法,我希望这里的任何人都可以告诉我我是对还是错,或者有什么我没有考虑或误解的地方。

我目前的理解是我应该将参数作为 const 引用传递。如果我按值传递,那么当我创建Outfit 的实例时,例如Shirt 将被复制。如果我理解正确,这可能很危险。副本和原始 Outfit 将指向同一个 Shirt 实例。而且这种共享所有权模式很危险,因为我们不知道 Shirt 是否会被释放。

这种理解正确吗?还是我过于复杂了?

【问题讨论】:

  • 你的理解有误。 shirt 是一个 value 成员,这意味着编译器生成的默认复制构造函数将在需要时创建 shirt 的副本(因此是 brandcolor 的副本)复制Outfit 对象。您可能仍想使用const 引用来避免制作这些副本,但您不必担心多个对象共享成员。如果 shirtShirt* 而不是 Shirt,那么您必须更加小心 3/5/0 规则。
  • 如果您想拥有所有权,请使用指针或智能指针。上面的代码只是一个值。还是您的意思是 Shirt 稍后将作为共享内存模型与自身一起实现?
  • 如果通过引用共享对象,则需要担心对象的生命周期。如果一切都是副本,那就少了很多麻烦。
  • @NathanPierson 感谢您的帖子。这很有帮助。如果您发布作为答案,我会接受。感谢您的时间。

标签: c++ pointers


【解决方案1】:

副本和原始 Outfit 将指向同一个 Shirt 实例

不,这是错误的。副本与原始副本没有关系,除非它还包含指针。在这种情况下,指针仍将指向它们在复制之前引用的任何内容。然而,即使是指针本身也不相同。所以做任何可能影响指针的事情,比如递增 (pointer++) 都不会影响另一个指针。

在任一

Outfit(Shirt shirt): shirt(shirt) {}

Outfit(const Shirt& shirt): shirt(shirt) {}

制作了一份副本。

如何完成取决于您选择哪一个。我认为第二个选项是首选,因为只调用复制构造函数来复制shirt 参数,但第一个将生成 copy 然后移动构造函数用于“将副本移动”到shirt 字段中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-09
    • 2014-05-08
    • 1970-01-01
    • 1970-01-01
    • 2019-09-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多