如何在调用派生类构造函数之前设置基类成员?

时间:2013-01-22 14:52:23

标签: c++ inheritance constructor components protected

我的应用程序的组件有一个基类,它提供了一些成员以及必须覆盖的函数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()
    {

    }
};

那么我怎样才能确保在调用派生类的构造函数之前初始化基类成员?

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

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

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

如何使Init受到保护,并将Set重命名为SetAndInit,并强制它在调用Init函数之前始终执行该操作。这会阻止您在设置基本成员之前调用Init并仍然为您提供相对类似的界面。