I know that additional initialization methods are evil, as they leave a very nasty option for having object half-constructed and as result all methods needs to check for this. But what about this situation?
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>();
}
I KNOW WHY IT CRASHES. The std::shared_ptr
in the main is not yet initialized with shared pointer to config instance, so constructor does not know how to make weak_from_this
and just raises std::bad_weak_ptr
exception because there are no valid std::shared_ptr
pointing to this
at constructor's call time.
The question is: how can I avoided the whole thing? I believe the only way I see would be to add separate initialization method, which is evil as I've already mentioned...
As note about real code: the constructors loads cfg_item
from external source. It is assumed that all cfg_item
s are available for the entire lifetime of config
. The weak pointers back to config
are mandatory, as cfg_item
must push all changes done to it back to config
to save to external source
Aucun commentaire:
Enregistrer un commentaire