在调用基类构造函数之前执行代码

时间:2016-10-24 16:33:27

标签: c++

class Base {
public:
    Base(int a, int b);
};

class Derived : public Base {
private:
    static std::pair<int, int> determine_a_and_b_(int k);
public:
    explicit Derived(int k);
};

Derived::Derived(int k) :
    // a, b from determine_a_and_b_(k)...
    Base(a, b) { }

在调用determine_a_and_b_之前,有没有办法在Derived的构造函数中调用a来获取值bBase::Base

似乎唯一的方法是重构Base,以便首先将其默认构造为空对象,然后使用ab进行初始化,像

Derived::Derived(int k) : Base() {
    Base::init_(a, b);
}

有没有更好的方法来做到这一点,而无需更改Base

修改 - 制作determine_a_and_b_静态

2 个答案:

答案 0 :(得分:3)

你可以在这里做的是编写一个返回Base的函数,并在函数中创建std::pair返回的determine_a_and_b_的基数。这允许您在成员初始化列表中有条件地初始化base。你会有像

这样的东西
class Base {
public:
    Base(int a, int b);
};

class Derived : public Base {
private:
    static std::pair<int, int> determine_a_and_b_(int k);
    static Base create_base(const std::pair<int, int>& params) { return Base(params.first, params.second); }
public:
    explicit Derived(int k);
};

Derived::Derived(int k) : Base(create_base(determine_a_and_b_(k)) {}

答案 1 :(得分:2)

在构造函数开始运行之前调用成员函数总是很阴暗。您最终在尚未构造的对象上运行代码。

一种替代方案是从第二个基础派生。首先选择该基类,选择a和b,然后使用它们来初始化你的第二个基类:

class Base {
public:
    Base(int a, int b){};
};

class Params
{
protected:
    Params()
    {
    // this replaces std::pair<int, int> determine_a_and_b_(int k);
    // put your logic here
        _values.first = 0;
        _values.second = 1;
    }
    std::pair<int, int> _values;
};

class Derived : public Params, public Base {
private:
public:
    explicit Derived(int k);
};

Derived::Derived(int k) :
    Base(_values.first, _values.second) 
{

}