类继承调用不同的构造函数
class inheritance call a different constructor
hei我有一个c++03类,它有一个接受整数的简单构造函数。以及一个具有序列化方法的派生类,该类应将文件名作为构造函数,从中加载整数,然后调用第一个构造函数。
class A {
public:
A(int foo);
}
和一个派生类:
class XmlableA : public A {
public:
XmlableA(int foo);
XmlableA(string xmlfilename) {
//load foo from xml
// call A::A(foo)
}
}
我尝试了一些不同的解决方案,但每次我得到
no matching function for call to ‘A::A()’
几乎所有的答案都是一样的,所以我建议一个不同的解决方案,这是我个人更喜欢的。
将static
成员函数Create
定义为:
class XmlableA : public A {
public:
XmlableA(int foo);
//static member function
static XmlableA Create(string const & xmlfilename)
{
//load foo from xml
int foo = /*load from file*/;
return XmlableA(foo);
}
};
用法:
XmlableA xmlable = XmlableA::Create(xmlFile);
初始化它,如下所示:
XmlableA(int foo) : A(foo) {}
您也可以考虑:
private:
static int LoadXML(const string& xmlfilename) {
int ret = ...; << load here
return ret;
}
public:
XmlableA(string xmlfilename) : A(LoadXML(xmlfilename)) {
}
在C++中,基类是在Child类之前构造的,因此您将无法执行此操作。您可以创建一个Factory,该Factory采用文件名并根据该文件中的内容创建对象。
示例:
class XmltableAFactory {
public:
static XmltableAFactory build(string xmlfilename) {
// read int foo from xmlfilename
return XmltableAFactory(foo);
}
};
然后这样称呼它:
XmltableA myObj = XmltableAFactory::build(filename);
有几点需要注意。
- 这意味着您将不需要
XmltableA
类中的string xmlfilename
协构造函数,因为如上所述,在调用基类的构造函数之前,您无法知道foo - 您可以选择通过值或通过指针从工厂返回。编译器可能会按值优化返回,因为您正在创建对象并在同一行返回它。然而,众所周知,通过指针返回通常会更快,但您必须创建一个
new
对象,然后确保在使用完delete
对象后将其返回 - 如果你不想浪费内存,可以看看boost的
auto_ptr
和shared_ptr
如果你想在调用A::A(int)
之前做点什么,你最终不得不破解,比如
int XmlableA::f(string filename) { /* load foo from xml */; return foo; }
XmlableA(string xmlfilename) : A(f(filename)) {}
好的,所以第一个很容易:
XmlableA::XmlableA(int foo) : A(foo)
{
}
第二个需要做类似的事情
XmlableA(string xmlfilename) : A(fooFromXML(xmlfilename))
{
}
我们可以实现为
class XmlableA : public A
{
static int fooFromXML(string filename);
public:
// ...
注意,加载XML文件并返回所需整数的fooFromXML
,必须是静态的,因为当我们调用它时,我们还没有XmlableA
实例来调用它。
对于多个参数(以及一般设计),工厂可能是最好的:如果你执着于构造函数模型,不关心效率,你可以这样做:
class XmlableA : public A
{
static int intFromXML(char const *varname, string const &filename);
public:
XmlableA(string const &xmlfilename)
: A(intFromXML("foo", xmlfilename), intFromXML("bar", xmlfilename))
{
}
如果您关心重复解析XML文件,而不关心可重入性,则可以通过将xFromXML
缓存在静态成员中来"记忆"它。
如果类A没有默认构造函数,则必须显式调用派生类的初始化列表中的构造函数。XmlableA(string fn) : A(readIntegerFromFile(fn)) {}
。
但是,您应该考虑将序列化"外包"到一个单独的类中。例如,如果您有一个类型为A
的对象,现在您想序列化它,会发生什么?您不能,因为您只能序列化XmlableA
。此外,如果您的客户决定不再需要XML序列化,而是使用Yaml或某些专有格式,会发生什么情况?您将不得不更改所有代码。
- 具有相同名称的类的构造函数继承
- 多复制构造函数继承中的惊人行为
- CRTP 和复制/移动赋值/构造函数继承
- 复制构造函数继承动态分配的数组
- 无法从 c++ 中的构造函数继承
- 在构造函数继承中使用默认构造函数
- 构造函数继承和直接成员初始化
- C++ - 使用私有参数的构造函数继承
- 通过可变参数模板进行C++11构造函数继承
- C++11构造函数继承和不带参数的构造函数
- C++11 - 构造函数继承
- C++构造函数继承
- 使用 C++11 编译器的构造函数继承正在生成错误
- 选择性构造函数继承"Ambiguous resolution"错误
- 什么是构造函数继承
- C++对象中的构造函数继承与方法继承
- C++构造函数继承没有匹配的函数
- C++构造函数继承(从派生类调用构造函数)
- 模板构造函数继承的标准符合语法是什么
- C++构造函数继承错误