继承构造函数
C++11 中提供的继承构造函数可以让派生类直接使用基类的构造函数,而无需自己再写构造函数,尤其是在基类有很多构造函数的情况下,可以极大地简化派生类构造函数的编写。先来看没有继承构造函数之前的处理方式:
#include <iostream>
#include <string>
using namespace std;
class Base
{
public:
Base(int i) :m_i(i) {}
Base(int i, double j) :m_i(i), m_j(j) {}
Base(int i, double j, string k) :m_i(i), m_j(j), m_k(k) {}
int m_i;
double m_j;
string m_k;
};
class Child : public Base
{
public:
Child(int i) :Base(i) {}
Child(int i, double j) :Base(i, j) {}
Child(int i, double j, string k) :Base(i, j, k) {}
};
int main()
{
Child c(520, 13.14, "i love you");
cout << "int: " << c.m_i << ", double: "
<< c.m_j << ", string: " << c.m_k << endl;
return 0;
}
通过测试代码可以看出,在子类中初始化从基类继承的类成员,需要在子类中重新定义和基类一致的构造函数,这是非常繁琐的,C++11 中通过添加继承构造函数这个新特性完美的解决了这个问题,使得代码更加精简。
继承构造函数的使用方法是这样的:通过使用 using 类名::构造函数名(其实类名和构造函数名是一样的)来声明使用基类的构造函数,这样子类中就可以不定义相同的构造函数了,直接使用基类的构造函数来构造派生类对象。
#include <iostream>
#include <string>
using namespace std;
class Base
{
public:
Base(int i) :m_i(i) {}
Base(int i, double j) :m_i(i), m_j(j) {}
Base(int i, double j, string k) :m_i(i), m_j(j), m_k(k) {}
int m_i;
double m_j;
string m_k;
};
class Child : public Base
{
public:
using Base::Base;
};
int main()
{
Child c1(520, 13.14);
cout << "int: " << c1.m_i << ", double: " << c1.m_j << endl;
Child c2(520, 13.14, "i love you");
cout << "int: " << c2.m_i << ", double: "
<< c2.m_j << ", string: " << c2.m_k << endl;
return 0;
}
在修改之后的子类中,没有添加任何构造函数,而是添加了 using Base::Base; 这样就可以在子类中直接继承父类的所有的构造函数,通过他们去构造子类对象了。
另外如果在子类中隐藏了父类中的同名函数,也可以通过 using 的方式在子类中使用基类中的这些父类函数:
#include <iostream>
#include <string>
using namespace std;
class Base
{
public:
Base(int i) :m_i(i) {}
Base(int i, double j) :m_i(i), m_j(j) {}
Base(int i, double j, string k) :m_i(i), m_j(j), m_k(k) {}
void func(int i)
{
cout << "base class: i = " << i << endl;
}
void func(int i, string str)
{
cout << "base class: i = " << i << ", str = " << str << endl;
}
int m_i;
double m_j;
string m_k;
};
class Child : public Base
{
public:
using Base::Base;
using Base::func;
void func()
{
cout << "child class: i'am luffy!!!" << endl;
}
};
int main()
{
Child c(250);
c.func();
c.func(19);
c.func(19, "luffy");
return 0;
}
上述示例代码输出的结果为:
child class: i'am luffy!!!
base class: i = 19
base class: i = 19, str = luffy
子类中的 func() 函数隐藏了基类中的两个 func() 因此默认情况下通过子类对象只能调用无参的 func(),在上面的子类代码中添加了 using Base::func; 之后,就可以通过子类对象直接调用父类中被隐藏的带参 func() 函数了