Mik*_*ins 3 c++ inheritance constructor
我正在为以下情况寻找一个干净的C++习语:
class SomeLibraryClass {
public:
SomeLibraryClass() { /* start initialization */ }
void addFoo() { /* we are a collection of foos */ }
void funcToCallAfterAllAddFoos() { /* Making sure this is called is the issue */ }
};
class SomeUserClass : public SomeLibraryClass {
public:
SomeUserClass() {
addFoo();
addFoo();
addFoo(); // SomeUserClass has three foos.
}
};
class SomeUserDerrivedClass : public SomeUserClass {
public:
SomeUserDerrivedClass() {
addFoo(); // This one has four foos.
}
};
Run Code Online (Sandbox Code Playgroud)
所以,我真正想要的是SomeLibraryClass在构造过程结束时强制执行funcToCallAfterAllAddFoos的调用.用户不能将它放在SomeUserClass :: SomeUserClass()的末尾,这会弄乱SomeUserDerrivedClass.如果他把它放在SomeUserDerrivedClass的末尾,那么它永远不会被SomeUserClass调用.
为了进一步说明我的需要,想象一下/*start initialization*/获取一个锁,funcToCallAfterAllAddFoos()释放一个锁.
该编译器知道什么时候所有完成对象的初始化,但我可以通过一些不错的把戏在这个信息得到什么?
我可能会用某种工厂来实现它.以下代码应该被读作伪代码,我还没有尝试编译它或任何东西.
class LibraryClass
{
public:
template<typename D>
static D *GetNewInstance()
{
// by assigning the new D to a LibraryClass pointer, you guarantee it derives from LibraryClass at compile time
// that way, the user can't accidentally type "LibraryClass::GetNewInstance<int>()" and have it work
LibraryClass *c = new D();
c->funcToCallAfterAllAddFoos();
return c;
}
...
};
Run Code Online (Sandbox Code Playgroud)
我不确定这是可能的.但是,你可以稍微重新设计一下:给你的基类构造函数一个参数std::vector<Foo> const &foosToBeAdded,让派生类传递正确的foos:
class SomeLibraryClass {
public:
SomeLibraryClass(std::vector<Foo> const &foosToBeAdded) {
/* start initialization */
std::for_each(foosToBeAdded.begin(), foosToBeAdded.end(),
std::bind1st(std::mem_fun(&SomeLibraryClass::addFoo), this));
funcToCallAfterAllAddFoos();
}
private:
void addFoo(Foo const &someFoo) { /* we are a collection of foos */ }
void funcToCallAfterAllAddFoos() { /* this is now called at the right time */ }
};
class SomeUserClass : public SomeLibraryClass {
public:
SomeUserClass() :
SomeLibraryClass(makeAFooVector())
{
}
private:
std::vector<Foo> makeAFooVector() { /* return a vector with three Foos */ }
};
Run Code Online (Sandbox Code Playgroud)
该模式可以通过使被扩展SomeUserClass构造也接收vector的Foo第 然后Foo在调用基类构造函数之前,它会将自己的s 添加到列表中.
您也可以传递迭代器而不是vectors.留下来作为锻炼.