簡體   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