[英]static std::shared_ptr<T> member; vs std::shared_ptr<T> member;?
現在,我想,我必須在我的計划中做出一個重要的決定。 任務如下:
我有一個class base
,它將被多個派生類繼承。 派生類必須對base
成員的相同實例具有共享訪問權限。 另外,我想從外部訪問那些“共享” Base
的成員:從包含所有派生類的第三個class Foo
。 根據我目前的經驗,我想出了兩個解決方案:
structs
、 int
並將所有內容都放在構造函數中。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_1
和m_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_1
和m_2
包含在其中。
一種方法比另一種方法有什么優勢嗎?
一種的優點是程序中只有一個成員,另一種的優點是每個實例都有一個成員。
什么是更常見的方法,為什么?
非靜態成員通常更有用。 Static存儲是全局state,有問題,不鼓勵。
目前尚不清楚為什么Foo
具有成員m_1
和m2
,它們似乎指向與成員指向的 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.