依赖初始化列表
Depended initializatoin list
我是 C++ 的新手,遇到了这个设计问题。
假设我有这些 classes:
class Dependee
{
public:
// Constructors
initialize();
};
class Depender
{
public:
Depender(Dependee dependee);
// Other constructors and stuff
};
class World
{
public:
World();
private:
Dependee dependee_;
Depender depender_;
};
现在depender依赖dependee进行构建。但是dependee不仅要在depender的构造之前构造,还要使用initialize()进行初始化。
有几种方法可以解决这个问题,我正在考虑的两个是World里面的静态方法class
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++ 设计和编码约定的好书?
谢谢!
无论哪种方式,您都在生成大量副本。我会用共享指针来做,除非你真的 需要 将 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 个副本。
两阶段初始化通常是不明智的。 C++有构造函数!但是,考虑到它来自第三方库并且您对此无能为力,我当然不建议为您的 Depender 使用默认构造函数。发明构造函数(当然,还有其他一些东西)是为了保留 class 不变量。
您的静态初始化程序的问题当然是您的 Dependee 的复制构造。现在,您需要在您的依赖者 class 中复制一份您的依赖者的副本吗?或者指针可以吗?显然,如果是指针,你可以简单地使用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);
这应该工作得很好。
我是 C++ 的新手,遇到了这个设计问题。
假设我有这些 classes:
class Dependee
{
public:
// Constructors
initialize();
};
class Depender
{
public:
Depender(Dependee dependee);
// Other constructors and stuff
};
class World
{
public:
World();
private:
Dependee dependee_;
Depender depender_;
};
现在depender依赖dependee进行构建。但是dependee不仅要在depender的构造之前构造,还要使用initialize()进行初始化。
有几种方法可以解决这个问题,我正在考虑的两个是World里面的静态方法class
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++ 设计和编码约定的好书?
谢谢!
无论哪种方式,您都在生成大量副本。我会用共享指针来做,除非你真的 需要 将 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 个副本。
两阶段初始化通常是不明智的。 C++有构造函数!但是,考虑到它来自第三方库并且您对此无能为力,我当然不建议为您的 Depender 使用默认构造函数。发明构造函数(当然,还有其他一些东西)是为了保留 class 不变量。
您的静态初始化程序的问题当然是您的 Dependee 的复制构造。现在,您需要在您的依赖者 class 中复制一份您的依赖者的副本吗?或者指针可以吗?显然,如果是指针,你可以简单地使用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);
这应该工作得很好。