依赖初始化列表

时间:2015-09-23 13:24:36

标签: c++ constructor initialization

我是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 ++设计和编码约定的好书?

谢谢!

2 个答案:

答案 0 :(得分:1)

你正在以任何方式产生大量副本。除非你真的需要DependeeWorld中存储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);

这应该合理地运作。