繁体   English   中英

static std::shared_ptr<t> 成员; vs std::shared_ptr<t> 成员;?</t></t>

[英]static std::shared_ptr<T> member; vs std::shared_ptr<T> member;?

现在,我想,我必须在我的计划中做出一个重要的决定。 任务如下:

我有一个class base ,它将被多个派生类继承。 派生类必须对base成员的相同实例具有共享访问权限。 另外,我想从外部访问那些“共享” Base的成员:从包含所有派生类的第三个class Foo 根据我目前的经验,我想出了两个解决方案:

  • 第一个是使用共享指针。 为简单起见,使用structsint并将所有内容都放在构造函数中。
struct Base
{
  std::shared_ptr<int> m_1 = nullptr;
  std::shared_ptr<int> m_2 = nullptr;
};

struct Derived_1 : Base
{
  // using Base members and doing other stuff
};

struct Derived_2 : Base
{
  // using Base members and doing other stuff
};

struct Foo
{
  std::shared_ptr<int> m_1 = std::make_shared<int>();
  std::shared_ptr<int> m_2 = std::make_shared<int>();

  Derived_1 _d1;
  Derived_2 _d2;

  Foo()
  {
    _d1.m_1 = this->m_1;
    _d1.m_2 = this->m_2;

    _d2.m_1 = this->m_1;
    _d2.m_2 = this->m_2;
  }
};

我可以从Foo以及派生类访问相同的m_1m_2

  • 第二种解决方案涉及使用static关键字:
struct Base
{
  static std::shared_ptr<int> m_1;
  static std::shared_ptr<int> m_2;
};

// providing definitions for Base::m_1 and Base::m_2 ...

// Derived classes stay the same as in first example.

class Foo
{
  std::shared_ptr<int> m_1;
  std::shared_ptr<int> m_2;

  Foo()
  {
    this->m_1 = Base::m_1;
    this->m_2 = Base::m_2;
  }

};

在这两种情况下,我都取得了相同的结果(真的吗?)。 一种方法比另一种方法有什么优势吗? 他们有什么隐藏的缺点? 什么是更常见的方法,为什么? 我对其他方法很好奇。 我在VS17下使用c++17。

在这两种情况下,我都取得了相同的结果(真的吗?)。

嗯,没有。 如果使用 static 成员,则该成员不与任何实例关联,并且程序中分别只有一个共享的Base::m_1和一个Base::m_2 对于非静态成员, Base的每个实例都有自己的m_1m_2包含在其中。

一种方法比另一种方法有什么优势吗?

一种的优点是程序中只有一个成员,另一种的优点是每个实例都有一个成员。

什么是更常见的方法,为什么?

非静态成员通常更有用。 Static存储是全局state,有问题,不鼓励。


目前尚不清楚为什么Foo具有成员m_1m2 ,它们似乎指向与成员指向的 object 相同的 object 。 为什么不简单地使用这些指针并摆脱Foo中的指针?

struct Foo
{
  Derived_1 _d1{std::make_shared<int>(), std::make_shared<int>()};
  Derived_2 _d2{_d1.m_1,                 _d1.m_2};
};

共享派生对象的基类也是可能的,这将实现每个Foo实例只有一个共享指针副本。 但只有当派生实例本身是单个派生 class 的基础时才有可能。 在这种情况下,通过虚拟 inheritance 实现基地的共享。

struct Derived_1 : virtual Base {};
struct Derived_2 : virtual Base {};
struct Derived   : Derived_1, Derived_2 {
    Derived(std::shared_ptr<int> m_1, std::shared_ptr<int> m_2): Base{m_1, m_2} {}
};

struct Foo
{
  Derived _d{std::make_shared<int>(), std::make_shared<int>()};
};

他们不一样。 考虑一下:

int main() {
    Foo f1;
    Foo f2;
    *(f1.m_1) = 5;
    *(f2.m_1) = 42;
    std::cout << *(f1.m_1);
}

对于没有static的第一个版本,它将 output: 5 ,因为每个Foo实例都使用自己的Base子对象。 第二种变体有一些错误:

#include <memory>
#include <iostream>
struct Base
{
  static std::shared_ptr<int> m_1;
  static std::shared_ptr<int> m_2;
};

// defintions were missing
std::shared_ptr<int> Base::m_1 = std::make_shared<int>();
std::shared_ptr<int> Base::m_2 = std::make_shared<int>();

// Foo didnt inherit from Base and had a private constructor
struct Foo : Base
{
  std::shared_ptr<int> m_1;
  std::shared_ptr<int> m_2;

  Foo()
  {
    this->m_1 = Base::m_1;
    this->m_2 = Base::m_2;
  }
};

修复后,上面的main打印42 ,因为只有一个Base::m_1和只有一个Base::m_2

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM