shared_from_this从构造函数中调用 [英] shared_from_this called from constructor

查看:172
本文介绍了shared_from_this从构造函数中调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须在容器中创建一个对象。没有智能指针我会使用这样的:

  a_class :: a_class()
{
register_somewhere(this);
}



使用智能指针应该使用 shared_from_this 但是我不能在构造函数中使用它。



有没有一个 clean 方法来解决这个问题?在类似的情况下你会做什么?
我正在考虑引入一个 init 方法在创建后调用,并将所有内容放在工厂函数中,如下所示:

  boost :: shared_ptr< a_class> create_a()
{
boost :: shared_ptr< a_class> ptr(new a_class);
ptr-> init();
return ptr;
}

在这种情况下是否有标准程序? / p>

编辑:实际上,我的情况更复杂。我有2个对象应该保持指针彼此。所以事实是我不是注册,而是创建另一个对象(让我们说 b_class ),它需要 this 参数。 b_class 接收这个作为弱指针并存储它。



我添加了这个,因为你给我设计建议(非常感谢)至少你可以知道我在做什么:

  a_class :: a_class()
{
b = new b_class(this);
}

在我的程序 a_class 是一个实体, b_class 是表示状态的具体类之一(在构造函数中它只是起始状态)。 a_class 需要指向当前状态的指针, b_class 需要操作该实体。



a_class 负责创建和销毁b_class实例,从而维护一个shared_ptr,但 b_class 需要操作 a_class ,从而维护一个弱指针。 a_class 实例存活 b_class 实例。



您建议在这种情况下避免使用智能指针?

解决方案


a_class 负责创建和销毁 b_class 实例


...


a_class 实例survives b_class 实例。


鉴于这两个事实,应该没有危险, b_class 实例可以尝试在 a_class 实例被销毁后访问 a_class 因为 a_class 实例负责销毁 b_class 实例。



b_class 只能保存指向它的关联 a_class 实例的指针。原始指针不表示适用于这种情况的任何所有权。



在这个例子中, a_class 被创建,动态地,是聚合对象的一部分等。无论创建 a_class 如何管理它的生命周期,如 a_class 管理它实例化的 b_class 的生命周期。



例如

  class a_class; 

class b_class
{
public:
b_class(a_class * a_):a(a_){}
private:
a_class *一个;
};

class a_class
{
public:
a_class():b(new b_class(this)){}
private:
boost :: shared_ptr< b_class> b;
};

注意,在这个玩具示例中,不需要 shared_ptr ,对象成员也会工作(假设你不复制你的实体类)。

  class a_class 
{
public:
a_class():b(this){}
private:
b_class b;
};


I have to register an object in a container upon its creation. Without smart pointers I'd use something like this:

a_class::a_class()
{
    register_somewhere(this);
}

With smart pointers I should use shared_from_this but I can't use that in the constructor.

Is there a clean way to solve this problem? What would you do in a similar situation? I'm thinking about introducing an init method to call just after creation and put everything in a factory function like this:

boost::shared_ptr<a_class> create_a()
{
    boost::shared_ptr<a_class> ptr(new a_class);
    ptr->init();
    return ptr;
}

Is it fine or there is a standard procedure to follow in such cases?

EDIT: Actually my case is more complex. I have 2 object which shall maintain pointers each other. So the truth is I'm not "registering" but creating another object (let's say b_class) which requires this as a parameter. b_class receives this as a weak pointer and stores it.

I'm adding this because since you are giving me design advices (which are very appreciated) at least you can know what I'm doing:

a_class::a_class()
{
    b = new b_class(this);
}

In my program a_class is an entity and b_class is one of the concrete classes representing the state (in the constructor it's just the starting state). a_class needs a pointer to the current state and b_class needs to manipulate the entity.

a_class is responsible for creating and destroying b_class instances and thus maintains a shared_ptr to them but b_class need to manipulate a_class and thus maintains a weak pointer. a_class instance "survives" b_class instances.

Do you suggest to avoid using smart pointers in this case?

解决方案

a_class is responsible for creating and destroying b_class instances

...

a_class instance "survives" b_class instances.

Given these two facts, there should be no danger that a b_class instance can attempt to access an a_class instance after the a_class instance has been destroyed as the a_class instance is responsible for destroying the b_class instances.

b_class can just hold a pointer to it's associated a_class instance. A raw pointer doesn't express any ownership which is appropriate for this case.

In this example it doesn't matter how the a_class is created, dynamically, part of a aggregated object, etc. Whatever creates a_class manages its lifetime just as a_class manages the lifetime of the b_class which it instantiates.

E.g.

class a_class;

class b_class
{
public:
    b_class( a_class* a_ ) : a( a_ ) {}
private:
    a_class* a;
};

class a_class
{
public:
    a_class() : b( new b_class(this) ) {}
private:
    boost::shared_ptr<b_class> b;
};

Note, in this toy example there is no need for a shared_ptr, an object member would work just as well (assuming that you don't copy your entity class).

class a_class
{
public:
    a_class() : b( this ) {}
private:
    b_class b;
};

这篇关于shared_from_this从构造函数中调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆