我的应用程序的组件有一个基类,它提供了一些成员以及必须覆盖的函数Init()
和Update()
。
class Component
{
public:
void Set(type* Member1, type* Member2, type* Member3)
{
this->Member1 = Member1;
this->Member2 = Member2;
this->Member3 = Member3;
}
virtual void Init() = 0;
virtual void Update() = 0;
virtual ~Component() {}
protected:
type* Member1;
type* Member2;
type* Member3;
};
对于管理组件,有一位经理。它首先设置组件的成员,然后在其上调用Init()
。稍后,它可用于更新所有已分配的组件,但与此问题无关。
class Manager
{
public:
void Add(string Name, Component* Component)
{
list[Name] = Component;
}
void Init(type* Member1, type* Member2, type* Member3)
{
for (auto i = list.begin(); i != list.end(); i++)
{
i->second->Set(Member1, Member2, Member3);
i->second->Init();
}
}
void Update()
{
for (auto i = list.begin(); i != list.end(); i++)
i->second->Update();
}
private:
unordered_map<string, Component*> list;
};
我对我的实现并不满意,因为我希望组件使用它们的构造函数进行初始化而不是覆盖Init()
函数。但是在施工时,基类成员还没有。
我知道我可以通过派生类构造函数传递成员,但我不希望特定组件关心它们的基类成员。这看起来像下面但是我不想要那个。
class Component
{
public:
Component(type* Member1, type* Member2, type* Member3)
{
this->Member1 = Member1;
this->Member2 = Member2;
this->Member3 = Member3;
}
virtual void Update() = 0;
virtual ~Component();
protected:
type* Member1;
type* Member2;
type* Member3;
};
class Specific : public Component
{
public:
Specific(type* Member1, type* Member2, type* Member3) : Component(Member1, Member2, Member3)
{
}
void Update()
{
}
};
那么我怎样才能确保在调用派生类的构造函数之前初始化基类成员?
答案 0 :(得分:1)
你真的没有选择。派生类知道基类的初始化需求(因为基类在其构造函数/初始化函数中需要该信息),或者您必须将派生类的初始化从其构造函数中移出(由客户端初始化基类后。)
如果需要在基类上设置的成员列表很长,您可以将它们全部打包在一个结构中,并通过派生类将它传递给基类。
答案 1 :(得分:0)
在派生类构造函数之前调用基类构造函数,因此在基类构造函数中设置值。
答案 2 :(得分:0)
我不太确定你在这里尝试做什么,但我可以做一些观察。看起来您可能正在尝试实施两阶段构建。
首先,如果要使用基类构造函数,则有来传递派生构造函数中的值。语言中没有其他机制可以做到,所以如果这不是一个选项(或者至少不是你想要娱乐的那个),那么你将不得不使用额外的外部接口。
要回答您的最后一个问题,在调用派生构造函数之前,始终初始化基类的成员。我假设您要确保在使用Update
之前设置它们。
如何使Init
受到保护,并将Set
重命名为SetAndInit
,并强制它在调用Init
函数之前始终执行该操作。这会阻止您在设置基本成员之前调用Init
并仍然为您提供相对类似的界面。