我必须在创建容器时在容器中注册它.没有智能指针,我会使用这样的东西:
a_class::a_class()
{
register_somewhere(this);
}
Run Code Online (Sandbox Code Playgroud)
使用智能指针我应该使用,shared_from_this但我不能在构造函数中使用它.
有没有一个干净的方法来解决这个问题?在类似的情况下你会做什么?我正在考虑init在创建之后引入一个方法来调用,并将所有内容放在像这样的工厂函数中:
boost::shared_ptr<a_class> create_a()
{
boost::shared_ptr<a_class> ptr(new a_class);
ptr->init();
return ptr;
}
Run Code Online (Sandbox Code Playgroud)
没有问题,或者在这种情况下有一个标准程序可以遵循?
编辑:其实我的情况更复杂.我有2个对象,它们将保持彼此的指针.所以事实是我不是"注册"而是创建另一个b_class需要this作为参数的对象(让我们说).作为弱指针b_class接收this并存储它.
我添加这个是因为你给我设计建议(非常感谢),至少你可以知道我在做什么:
a_class::a_class()
{
b = new b_class(this);
}
Run Code Online (Sandbox Code Playgroud)
在我的程序中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实例"幸存"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* a;
};
class a_class
{
public:
a_class() : b( new b_class(this) ) {}
private:
boost::shared_ptr<b_class> b;
};
Run Code Online (Sandbox Code Playgroud)
注意,在这个玩具示例中不需要a shared_ptr,对象成员也可以正常工作(假设您不复制实体类).
class a_class
{
public:
a_class() : b( this ) {}
private:
b_class b;
};
Run Code Online (Sandbox Code Playgroud)
如果在构造期间绝对需要shared_ptr,最好有一个'init'函数.事实上,这是我能想到的唯一体面的方法.init()如果选择此路径,您可能应该有一个特殊的函数来创建此类型的对象,以确保被调用.
但是,根据您注册的内容,使用构造函数中的对象的普通指针而不是shared_ptr来提供您正在注册的任何对象可能是更好的主意.然后在析构函数中,您可以从管理器中取消注册该对象.