我是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_;
};
现在,依赖项依赖于依赖于构造。但是dependee不仅必须在依赖者构造之前构造,而且还使用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;
}
Obvoiusly我对任何其他解决方案持开放态度,但请考虑Dependee来自外部库。
PS:你有没有关于正确的C ++设计和编码约定的好书?
谢谢!
答案 0 :(得分:1)
你正在以任何方式产生大量副本。除非你真的需要在Dependee
和World
中存储Depender
的单独副本,否则我会使用共享指针。
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_;
};
这样您只需构造并存储每个对象的1个副本。
答案 1 :(得分:1)
两阶段初始化通常是不明智的。 C ++有构造函数!但是,它来自第三方库,你无能为力,我肯定不会建议你的Depender使用默认构造函数。当然,发明了构造函数(当然还包括)以保留类不变量。
静态初始化程序的问题当然是您的Dependee的复制结构。现在,你需要在你的依赖者类中复制你的dependee吗?或指针会做什么?显然,如果它是指针,你可以简单地使用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);
这应该合理地运作。