我有一个简单的设置;两个类,一个继承自另一个。在继承的类中,我想从文件中读取并构造对象,但我的问题是因为基类必须在构造函数体之前初始化,即在初始化列表中,我必须打开文件两次。我想只打开一次文件,读入我需要的数据,关闭文件,然后初始化继承的对象。
有一个很好的方法吗?我的代码目前看起来像这样,并打开文件两次:
#include <utility>
#include <fstream>
using namespace std;
class foo{
protected:
int _a;
public:
foo(int a) : _a(a) {}
};
class bar : public foo{
private:
int _b;
pair<int, int> read_bar(string file_name) { // get a and b from a file }
public:
bar(string file_name) : foo(read_bar(file_name).first), _b(read_bar(file_name).second) {}
};
我希望能够做一些像一对初始化的东西,看起来像:
bar(string file_name) : (foo, _b)(read_bar(file_name)) {}
或者在读取文件后在函数体内初始化foo。如何才能做到这一点?我有一个想法,read_bar可以初始化_b然后传递一个int来构造foo?但这似乎不合逻辑,在类似的多重继承情况下无济于事。
这是我的第一个问题,请解释我是如何提出问题或编写代码的。
答案 0 :(得分:4)
我建议使用delegating constructor。
bar(string file_name) : bar(read_bar(file_name)) {} // Delegate to the next constructor.
bar(pair<int, int> in) : foo(in.first), _b(in.second) {}
<强> PS 强>
除非您有理由使read_bar
成为非static
成员函数,否则我建议您将其设为static
成员函数。在我看来,该函数不需要任何特定于实例的逻辑。
答案 1 :(得分:1)
foo::_a
为protected
,因此bar
可以直接访问它。您可以使用默认值构建foo
,并在读取文件后构建更新_a
。
#include <utility>
#include <fstream>
using namespace std;
class foo {
protected:
int _a;
public:
foo(int a) : _a(a) {}
};
class bar : public foo {
private:
int _b;
pair<int, int> read_bar(string filename) {
// get a and b from a file
}
public:
bar(string file_name) : foo(0) {
pair<int, int> values = read_bar(file_name);
_a = values.first;
_b = values second;
}
};