[英]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
我有以下代码:
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
}
}
但是 class Cohomology
也有由SubCohomology
实现的虚拟方法:
class SubCohomology : public Cohomology
{
public:
SubCohomology(PList params) {}
~Cohomology() {std::cout << "SubCohomology destroyed" << std::endl;}
// Implementation of the virtual methods
}
因此,用于检查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);
}
代码编译,但运行它会产生这个错误:
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)
这发生在 function initializeField
之后。 这是一个 memory 问题,可能与尝试free()
不存在的资源有关。
我怀疑使用std::enable_shared_from_this可能有助于解决这个问题,但考虑到我的特殊问题,我不知道如何实现强制性 inheritance,因为我正在尝试初始化std::shared_ptr<Cohomology> coh
class 成员上Cohomology class
中的一个字段。
此处概述的示例对于理解如何使用它非常有帮助,但我不知道是否必须在EMField
中嵌套另一个结构来实现它。 我也理解在这个问题中解决的问题:我们什么时候应该使用 std::enable_shared_from_this ,但我不能把它放在结构有std::shared_ptr
作为成员的上下文中。
请理解可能会添加许多EMField
对象,其std::shared_ptr<Cohomology>
成员将所有字段指向相同的 object
谢谢你。
std::shared_ptr
的存在是为了管理动态分配对象的生命周期。 对于具有自动存储持续时间(如coh
)的 object,不需要(或不可能)此类管理。 它的使用寿命与其封闭的 scope 相关。 因此,指向coh
的指针绝不能由std::shared_ptr
管理。
相反,您应该考虑在接受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);
}
如果您绝对不想将您的上Cohomology
EMField
从调用者传递到 EMField 中,并且所有上Cohomology
对象都应该动态分配,并且它们都应该由std::shared_ptr
管理,那么,只有这样,是std::enable_shared_from_this
工作的工具。
例子:
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);
}
请注意,上同SubCohomology
上Cohomology
现在具有非公共构造函数。 如果您从std::enable_shared_from_this
继承,则不应允许任何对象不被std::shared_ptr
管理,因此需要单独的工厂函数来确保这一事实。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.