0

我的应用程序的组件有一个基类,它提供了一些成员和功能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()
    {

    }
};

那么如何确保在调用派生类的构造函数之前初始化基类成员呢?

4

3 回答 3

1

你真的别无选择。派生类知道基类的初始化需求(因为基类在其构造函数/初始化函数中需要该信息),或者您必须将派生类的初始化移出其构造函数(由初始化基类后的客户端)。

如果需要在基类上设置的成员列表很长,您可以将它们全部打包在一个结构中,然后通过派生类将其传递给基类。

于 2013-01-22T15:21:59.570 回答
0

基类构造函数在派生类构造函数之前调用,因此请在基类构造函数中设置值。

于 2013-01-22T14:56:50.393 回答
0

我不太确定你想在这里完成什么,但我可以做一些观察。看起来您可能正在尝试实施两阶段构建。

首先,如果要使用基类构造函数,则必须传递派生构造函数的值。语言中没有其他机制可以做到这一点,所以如果这不是一个选项(或者至少不是你想要娱乐的选项),那么你将不得不使用一个额外的外部接口。

为了回答您的最后一个问题,基类的成员始终在调用派生构造函数之前进行初始化。例如,我假设您想确保在使用之前设置它们Update

怎么做Init受保护,并重命名Set为类似的东西SetAndInit并强制它在调用Init函数之前总是做集合。这可以防止您Init在设置基本成员之前调用,并且仍然为您提供相对相似的界面。

于 2013-01-22T15:19:02.773 回答