依赖初始化列表
Depended initializatoin list
我对c++有点陌生,遇到了这个设计问题。
假设我有这些类:
class Dependee
{
public:
// Constructors
initialize();
};
class Depender
{
public:
Depender(Dependee dependee);
// Other constructors and stuff
};
class World
{
public:
World();
private:
Dependee dependee_;
Depender depender_;
};
现在,依赖于依赖的构造。但是depended不仅要在dependder的构造之前被构造,而且要使用initialize()进行初始化。
有几种方法可以解决这个问题,我正在考虑的两种方法是在World类 中使用静态方法。static Dependee initDependee()
{
Dependee dependee();
if(!dependee.initialize())
{
throw SomeException();
}
return dependee;
}
,然后做:
World::World():
dependee_(initDependee()),
depender_(dependee_)
{}
或者使用默认构造函数初始化两者,并在World的构造函数
中完成其余的工作。World::World() :
dependee_(),
depender_()
{
Dependee dependee();
dependee.initialize();
dependee_ = dependee;
Depender depender(dependee);
depender_ = depender;
}
显然,我对任何其他解决方案都持开放态度,但考虑到Dependee来自外部库。
PS:您能推荐一些关于c++设计和编码规范的好书吗?
谢谢!
两阶段初始化通常是不明智的。c++有构造函数!然而,考虑到它来自第三方库,并且您对此无能为力,我当然不建议为您的依赖程序使用默认构造函数。构造函数的发明(当然还有其他一些东西)是为了保持类不变量。
静态初始化器的问题当然是依赖对象的复制构造。现在,在依赖类中需要依赖对象的副本吗?或者一个指针也行?显然,如果它是指针,您可以简单地使用unique_ptr。有什么问题吗?当然,动态分配,这并不总是首选。
那么你如何解决这个困境呢?我建议用包装纸。像这样:
template <class WRAPPEE> struct Wrapper {
Wrapper() { wrappee.initialize(); }
WRAPPEE& operator() { return wrappee; } // Add const version as well
private:
WRAPPEE wrappee;
};
typedef Wrapper<Dependee> dependee_t;
dependee_t dependee;
....
depender(dependee);
无论哪种方式,你都在生成大量副本。我会使用共享指针,除非你真的需要在World
和Depender
中存储Dependee
的单独副本。
class Dependee
{
public:
// Constructors
initialize();
};
class Depender
{
public:
Depender(shared_ptr<Dependee> dependee);
// Other constructors and stuff
};
class World
{
public:
World() : dependee_(new Dependee())
{
dependee_.initialize();
depender_.reset(new Depender(dependee_));
}
private:
shared_ptr<Dependee> dependee_;
shared_ptr<Depender> depender_;
};
这样你只构造和存储每个对象的一个副本。
相关文章:
- 复制列表初始化的隐式转换的等级是多少
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 我使用向量来创建类对象列表.初始化向量时如何使用参数调用构造函数?
- C++11 中的混合列表初始化
- 我可以列表初始化 std::vector 并完美转发元素吗?
- 无法在声明时使用初始值设定项列表初始化常量字符*/字符串数组的向量
- C++20 从括号中的值列表初始化聚合,不支持内部数组
- 如何在向量列表初始化时避免对象复制以及如何延长临时的生存期
- 默认参数和空列表初始化
- 如何在列表初始化中放置额外的语句?
- C++列表初始化允许多个用户定义的转换
- 列表初始化是否将原子初始化为零
- 使用可变模板列表初始化数组,并放置new
- 使用整数初始化列表初始化长双精度的向量
- 直接列表初始化的自动规则
- 使用初始化列表初始化unique_ptr的容器,继续
- 如何修复"非聚合无法使用初始值设定项列表初始化" <map>
- 直接列表初始化和复制列表初始化之间的差异
- 为什么我可以在不使用赋值运算符的情况下使用列表初始化普通数组
- C++ - 使用类中的初始值设定项列表初始化动态集