[英]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.