[英]Initializing a member with type std::shared_ptr<B> of a class A with a pointer to class B in a member function of B
I have the following code:
我有以下代码:
class Cohomology;
struct EMField
{
std::shared_ptr<Cohomology> coh;
std::array<DIM> data;
// other methods
}
class Cohomology
{
private:
// private members
public:
Cohomology(PList params)
{
// Constructor of the class
}
virtual ~Cohomology() {std::cout << "Cohomology destroyed" << std::endl;}
void initializeField(EMField& field)
{
field.coh.reset(this);
// other methods to initialize field.data using the private members
}
}
But the class Cohomology
also has virtual methods that are implemented by SubCohomology
:但是 class
Cohomology
也有由SubCohomology
实现的虚拟方法:
class SubCohomology : public Cohomology
{
public:
SubCohomology(PList params) {}
~Cohomology() {std::cout << "SubCohomology destroyed" << std::endl;}
// Implementation of the virtual methods
}
So a test code to check whether EMFields
are initialized and can be manipulated looks like:因此,用于检查
EMFields
是否已初始化并可以操作的测试代码如下所示:
int main(int argc, char *argv[])
{
// variables needed to initialize PList params
PList params(); // construct params
SubCohomology coh(params);
EMField field;
coh.initializeField(field);
}
The code compiles, but running it yields this error:代码编译,但运行它会产生这个错误:
SubCohomology destroyed
Cohomology destroyed
free(): invalid pointer
[machine:324808] *** Process received signal ***
[machine:324808] Signal: Aborted (6)
[machine:324808] Associated errno: Unknown error 32767 (32767)
[machine:324808] Signal code: (24)
[machine:324808] [ 0] /usr/lib/libc.so.6(+0x38a40)[0x7f4ac0054a40]
[machine:324808] [ 1] /usr/lib/libc.so.6(+0x884dc)[0x7f4ac00a44dc]
[machine:324808] [ 2] /usr/lib/libc.so.6(gsignal+0x18)[0x7f4ac0054998]
[machine:324808] [ 3] /usr/lib/libc.so.6(abort+0xd7)[0x7f4ac003e53d]
[machine:324808] [ 4] /usr/lib/libc.so.6(+0x7c67e)[0x7f4ac009867e]
[machine:324808] [ 5] /usr/lib/libc.so.6(+0x9226c)[0x7f4ac00ae26c]
[machine:324808] [ 6] /usr/lib/libc.so.6(+0x940bc)[0x7f4ac00b00bc]
[machine:324808] [ 7] /usr/lib/libc.so.6(__libc_free+0x73)[0x7f4ac00b2a33]
[machine:324808] [ 8] /home/user/builddir/test_fields(_ZN13EMFieldILi0ELi1EED2Ev+0x83)[0x556db1fc0f73]
[machine:324808] [ 9] /home/user/builddir/test_fields(main+0x36e)[0x556db1fa205e]
[machine:324808] [10] /usr/lib/libc.so.6(+0x232d0)[0x7f4ac003f2d0]
[machine:324808] [11] /usr/lib/libc.so.6(__libc_start_main+0x8a)[0x7f4ac003f38a]
[machine:324808] [12] /home/user/builddir/test_fields(_start+0x25)[0x556db1fa3ba5]
[machine:324808] *** End of error message ***
Aborted (core dumped)
which happens after the function initializeField
.这发生在 function
initializeField
之后。 It is a memory problem, which might be related to trying to free()
a non-existing resource.这是一个 memory 问题,可能与尝试
free()
不存在的资源有关。
I suspect that using std::enable_shared_from_this might be helpful to address this problem but I don't know how to implement the mandatory inheritance considering my particular problem, as I am trying to initialize the std::shared_ptr<Cohomology> coh
class member of a field in the Cohomology class
.我怀疑使用std::enable_shared_from_this可能有助于解决这个问题,但考虑到我的特殊问题,我不知道如何实现强制性 inheritance,因为我正在尝试初始化
std::shared_ptr<Cohomology> coh
class 成员上Cohomology class
中的一个字段。
The example outlined here is very helpful to understand how to use this, but I don't know if I would have to nest another struct in EMField
to implement this. 此处概述的示例对于理解如何使用它非常有帮助,但我不知道是否必须在
EMField
中嵌套另一个结构来实现它。 I also understand the problem solved in this question: when should we use std::enable_shared_from_this , but I cannot put it in the context where a struct has a std::shared_ptr
as a member.我也理解在这个问题中解决的问题:我们什么时候应该使用 std::enable_shared_from_this ,但我不能把它放在结构有
std::shared_ptr
作为成员的上下文中。
Please understand that many EMField
objects might be added, whose std::shared_ptr<Cohomology>
member points for all fields to the same object请理解可能会添加许多
EMField
对象,其std::shared_ptr<Cohomology>
成员将所有字段指向相同的 object
Thank you.谢谢你。
std::shared_ptr
exists to manage the lifetime of dynamically-allocated objects. std::shared_ptr
的存在是为了管理动态分配对象的生命周期。 No such management is needed (or possible) for an object with automatic storage duration (like
coh
).对于具有自动存储持续时间(如
coh
)的 object,不需要(或不可能)此类管理。 Its lifetime is tied to its enclosing scope.
它的使用寿命与其封闭的 scope 相关。
Therefore a pointer to
coh
must never be managed by a std::shared_ptr
.因此,指向
coh
的指针绝不能由std::shared_ptr
管理。
Instead, you should consider creating a constructor in EMField
that accepts a std::shared_ptr<Cohomology>
and having the caller create an appropriate dynamically-allocated object:相反,您应该考虑在接受
std::shared_ptr<Cohomology>
的EMField
中创建一个构造函数,并让调用者创建一个适当的动态分配的 object:
struct EMField
{
std::shared_ptr<Cohomology> coh;
// ...
EMField(std::shared_ptr<Cohomology> c)
: coh{c}
{}
// ...
};
int main(int argc, char *argv[])
{
// variables needed to initialize PList params
PList params(); // construct params
auto coh = std::make_shared<SubCohomology>(params);
EMField field(coh);
// No longer needed since EMField's constructor initializes its
// fields now
// coh.initializeField(field);
}
If you absolutely don't want to have to pass your Cohomology
object into EMField
from the caller, and all Cohomology
objects should be dynamically-allocated, and they should all be managed by std::shared_ptr
s, then, and only then, is std::enable_shared_from_this
the tool for the job.如果您绝对不想将您的上
Cohomology
EMField
从调用者传递到 EMField 中,并且所有上Cohomology
对象都应该动态分配,并且它们都应该由std::shared_ptr
管理,那么,只有这样,是std::enable_shared_from_this
工作的工具。
Example:例子:
class Cohomology : public std::enable_shared_from_this<Cohomology>
{
private:
// private members
protected:
Cohomology(PList params)
{
// Constructor of the class
}
Cohomology(const Cohomology&) = delete;
public:
virtual ~Cohomology()
{
std::cout << "Cohomology destroyed\n";
}
static std::shared_ptr<Cohomology> create(PList params)
{
return std::shared_ptr<Cohomology>(new Cohomology(params));
}
void initializeField(EMField& field)
{
field.coh = shared_from_this();
// ...
}
// ...
};
class SubCohomology : public Cohomology
{
private:
SubCohomology(PList params)
: Cohomology(params)
{}
public:
~SubCohomology()
{
std::cout << "SubCohomology destroyed\n";
}
static std::shared_ptr<SubCohomology> create(PList params)
{
return std::shared_ptr<SubCohomology>(new SubCohomology(params));
}
// Implementation of the virtual methods
};
int main(int argc, char *argv[])
{
// variables needed to initialize PList params
PList params; // construct params
std::shared_ptr<SubCohomology> coh = SubCohomology::create(params);
EMField field;
coh->initializeField(field);
}
Note that Cohomology
and SubCohomology
now have non-public constructors.请注意,上同
SubCohomology
上Cohomology
现在具有非公共构造函数。 If you inherit from std::enable_shared_from_this
you should not allow any objects to ever not be managed by a std::shared_ptr
, so separate factory functions are needed to ensure that fact.如果您从
std::enable_shared_from_this
继承,则不应允许任何对象不被std::shared_ptr
管理,因此需要单独的工厂函数来确保这一事实。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.