【发布时间】:2016-09-23 05:32:08
【问题描述】:
我知道额外的初始化方法是邪恶的,因为它们留下了一个非常讨厌的选项来让对象半构建,因此所有方法都需要检查这一点。但是这种情况呢?
class config;
class cfg_item final
{
private:
friend class config;
cfg_item(std::weak_ptr<config> owner) : owner(owner) { }
std::weak_ptr<config> owner;
}
class config final : private std::enable_shared_from_this<config>
{
public:
config()
{
items.emplace(std::make_shared<cfg_item>(weak_from_this())); // Will crash!
}
private:
std::vector<std::shared_ptr<cfg_item>> items;
}
int main(int argc, char * argv[])
{
std::shared_ptr<config> cfg = std::make_shared<config>();
}
我知道它为什么会崩溃。 main 中的 std::shared_ptr 尚未使用指向配置实例的共享指针进行初始化,因此构造函数不知道如何创建 weak_from_this 并且只是引发 std::bad_weak_ptr 异常,因为没有有效的 std::shared_ptr 指向 this构造函数的调用时间。
问题是:我怎样才能避免整件事?我相信我看到的唯一方法是添加单独的初始化方法,正如我已经提到的那样,这是 evil...
关于真实代码的注释:构造函数从外部源加载cfg_item。假设所有cfg_items 在config 的整个生命周期内都可用。指向config 的弱指针是强制性的,因为cfg_item 必须将对其所做的所有更改推回config 以保存到外部源
【问题讨论】:
-
您可以在
cfg_item类中嵌入config的非拥有引用(如config&或std::reference_wrapper<config>)而不是weak_ptr<config>。它应该是安全的,因为从逻辑上讲,owner不会比config对象寿命长,除非你做一些非常疯狂的事情。 -
@FrankHB 这实际上是我三年前错过的一个非常好的主意。谢谢!
标签: c++11 design-patterns smart-pointers