简体   繁体   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;?

Right now, I think, I must make an important decision in my program.现在,我想,我必须在我的计划中做出一个重要的决定。 The task is the following:任务如下:

I have single class base which will be inherited by multiple derived classes.我有一个class base ,它将被多个派生类继承。 Derived classes must have shared access to same instances of base members.派生类必须对base成员的相同实例具有共享访问权限。 Also, I want to access those "shared" Base s members from outside: from a 3rd class Foo , which contains all derived classes.另外,我想从外部访问那些“共享” Base的成员:从包含所有派生类的第三个class Foo With my current experience I came up with two solutions:根据我目前的经验,我想出了两个解决方案:

  • first one is using shared pointers.第一个是使用共享指针。 Using structs , int s and putting everything in constructors for simplicity.为简单起见,使用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;
  }
};

This I have access to the same m_1 and m_2 from Foo and also from derived classes.我可以从Foo以及派生类访问相同的m_1m_2

  • second solution involves usage of static keyword:第二种解决方案涉及使用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;
  }

};

In both cases I achieve same result (do I really?).在这两种情况下,我都取得了相同的结果(真的吗?)。 Are there some advantages for one approach over the other?一种方法比另一种方法有什么优势吗? What are hidden drawbacks for them?他们有什么隐藏的缺点? What is more common approach and why?什么是更常见的方法,为什么? I am curious about other approaches.我对其他方法很好奇。 I am using c++17 under VS17.我在VS17下使用c++17。

In both cases I achieve same result (do I really?).在这两种情况下,我都取得了相同的结果(真的吗?)。

Well, no.嗯,没有。 If you use static member, then the member is not associated with any instance, and there is exactly one shared Base::m_1 and one Base::m_2 respectively in the program.如果使用 static 成员,则该成员不与任何实例关联,并且程序中分别只有一个共享的Base::m_1和一个Base::m_2 With a non-static member, every instance of Base have their own m_1 and m_2 contained within them.对于非静态成员, Base的每个实例都有自己的m_1m_2包含在其中。

Are there some advantages for one approach over the other?一种方法比另一种方法有什么优势吗?

One has the advantage that there is only one member in the program, and the other has the advantage that there is one member for each instance.一种的优点是程序中只有一个成员,另一种的优点是每个实例都有一个成员。

What is more common approach and why?什么是更常见的方法,为什么?

Non-static members are typically more useful.非静态成员通常更有用。 Static storage is global state, which is problematic and is discouraged. Static存储是全局state,有问题,不鼓励。


It is unclear why Foo has the members m_1 and m2 , which appear to point to the same object as members point to.目前尚不清楚为什么Foo具有成员m_1m2 ,它们似乎指向与成员指向的 object 相同的 object 。 Why not simply use those pointers and get rid of the pointers in Foo ?为什么不简单地使用这些指针并摆脱Foo中的指针?

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

Sharing the bases of the derived objects is also possible which would achieve having only a single copy of the shared pointers per instance of Foo .共享派生对象的基类也是可能的,这将实现每个Foo实例只有一个共享指针副本。 But it is only possible if the derived instances are themselves bases of a single derived class.但只有当派生实例本身是单个派生 class 的基础时才有可能。 In such case, the sharing of the base is achieved with virtual inheritance.在这种情况下,通过虚拟 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>()};
};

They are not the same.他们不一样。 Consider this:考虑一下:

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

For the first version without static it will output: 5 , because each Foo isntance uses its own Base subobject.对于没有static的第一个版本,它将 output: 5 ,因为每个Foo实例都使用自己的Base子对象。 The second variant has some errors:第二种变体有一些错误:

#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;
  }
};

After fixing that, the above main prints 42 , because there is only one Base::m_1 and only one 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