【问题标题】:C++ Sharing member variables to member instances of classes during initializationC++ 在初始化期间将成员变量共享给类的成员实例
【发布时间】:2022-12-09 00:18:31
【问题描述】:

当前使用 C++20。

我正在尝试在初始化期间将来自类 A 的实例的数据共享到它的 BC 的成员实例。我没有使用 getter/setter、单例、依赖注入等,而是想通过将它们作为参数传递到成员类变量的构造函数中来共享数据,其中每个成员实例将通过某种方式持有它们的数据份额(例如引用、原始指针、共享指针、空指针等)。

BC 旨在始终初始化为类 A 的成员。最终,A 应该是数据的最后一个“所有者”,这样当A 在销毁期间被释放时,共享数据应该与它一起被释放。考虑到这一点,这些方法中的哪一个是可以接受的?不违反任何重大规则并确保封装?

  1. A 将数据作为共享指针存储和传递。 B & C 将参数存储为共享指针。

  2. A 将数据存储为普通变量,并将它们作为空指针传递。 B & C 将参数存储为空指针。

  3. A 将数据存储为普通变量,并将它们作为引用传递。 B & C 将参数存储为引用。

  4. A 将数据存储为普通变量,并将它们作为原始指针传递。 B & C 将参数存储为原始指针。

    伪代码:

    class B
    {
    private:
      // Some variable that holds the shared data
    };
    
    class C
    {
    private:
      // Some variable that holds the shared data
    };
    
    class A
    {
      private:
        // Data to be shared to
        B b;
        C c;
    
        // Data to be shared
        SomeDataType first;
        SomeDataType second;
    
      public:
        A()
          : b{first, second}, c{first}
        {
    
        }
    };
    

【问题讨论】:

  • 注意“子类”通常是指继承。这些是成员BC 的实例。
  • 你为什么认为你需要智能指针?他们会解决什么问题?为什么不是原始指针?聪明的 poitners 帮助管理所有权,但这里没有什么可管理的。 A 有一个成员并且bc 都保证生命周期不长于A 实例
  • 我会选择选项 3)。此外,我还会在bc 之前声明firstsecond,以避免编译器警告并防止在初始化/销毁期间出错。
  • 我不会选择 3,因为引用成员具有原始指针所没有的某些含义(例如,没有副本)。原始拥有指针是您需要担心的。永远不会失效的原始非拥有指针是无害的
  • 另外,您是否打算在不使用A的情况下使用BC?那么谁将拥有这些数据?

标签: c++


【解决方案1】:

A 将数据作为共享指针存储和传递。 B & C 将参数存储为共享指针。

不。A 拥有数据,没有共享所有权。 ([...],A 应该是数据的最后一个“所有者”,这样当“A?”在销毁过程中被释放时,共享数据应该与它一起释放。”,如果它是最后一个和第一个那么它可以是唯一的,不需要共享。)

A 将数据存储为普通变量,并将它们作为空指针传递。 B & C 将参数存储为空指针。

不。void* 不是您没有的问题的解决方案。过去必须使用void*,现在有更好的选择。尽管首先这里没有必要,但这超出了这个答案的范围。

A 将数据存储为普通变量,并将它们作为引用传递。 B & C 将参数存储为引用。

不,也许是。引用成员具有含义。编译器无法为您生成复制。

A 将数据存储为普通变量,并将它们作为原始指针传递。 B & C 将参数存储为原始指针。

这听起来很合理。应该避免原始拥有指针。一个永远不会无效的原始非拥有指针(因为所有者在观察者之后被销毁)是可以的。您需要注意的唯一阶段是在构建和销毁期间不要使用尚未有效或不再有效的指针。值得一提的是,在 A 的构造过程中,可以使用指向成员的指针,但只有在初始化成员之后,您才可以安全地解除对指针的引用。

【讨论】:

  • 您可以在引用时复制它 - 您只需编写复制构造函数。
  • @lorro 对。不确定如何更好地制定它。实际上,我总是没有副本或没有参考成员。而且我不得不承认,我不知道如何在引用成员存在的情况下正确地实现副本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-23
  • 1970-01-01
  • 1970-01-01
  • 2010-09-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多