前言
首先我们来看一种情况,有如下示例:
class Base
{
public:
Base(int i):x(i),y(0){}
Base(int i,double j):x(i),y(j){}
Base(int i,double j,const string & str):x(i),y(j),s(str){}
private:
int x;
double y;
string s;
};
class Derived : Base
{
};
int main()
{
Derived d(1,3.2,"hello"); //error:没有合适的构造函数
return 0;
}
以上示例就是说,如果有一个派生类,希望能和基类一样采取相同的构造方式,其直接派生于基类是不能获取基类构造函数的,因为,C++派生类会隐藏基类同名函数。
所以Derived d(1,3.2,“hello”);调用会直接报错,因为派生类的默认构造函数隐藏了积累。如果希望使用基类的构造函数,一个可行的 方法就是在派生类中也定义这些构造函数并依次调用基类。
如下:
class Base
{
public:
Base(int i):x(i),y(0){}
Base(int i,double j):x(i),y(j){}
Base(int i,double j,const string & str):x(i),y(j),s(str){}
private:
int x;
double y;
string s;
};
class Derived : Base
{
public:
Derived(int i):Base(i){}
Derived(int i,double j):Base(i,j){}
Derived(int i,double j,const string & str):Base(i,j,str){}
};
int main()
{
Derived d1(1);
Derived d2(1,3.2);
Derived d3(1,3.2,"hello");
return 0;
}
继承构造函数
以上方法虽然可行,但是代码非常繁琐切重复性高,而C++11中的继承构造函数特征正是用于解决派生类隐藏基类同名函数的问题。
可以通过 using Base::SomeFunction来表示使用基类的同名函数。 所以以上示例,通过 using Base::Base;来声明使用基类的构造函数,就可以在派生类中不用定义相同的构造函数了,直接使用基类的构造函数来构造派生类对象。
class Base
{
public:
Base(int i):x(i),y(0){}
Base(int i,double j):x(i),y(j){}
Base(int i,double j,const string & str):x(i),y(j),s(str){}
private:
int x;
double y;
string s;
};
class Derived : Base
{
public:
using Base::Base; //声明使用基类的构造函数
};
int main()
{
Derived d1(1);
Derived d2(1,3.2);
Derived d3(1,3.2,"hello");
return 0;
}
需要注意的是,继承构造函数不会去初始化派生类新定义的数据成员。
考虑一种情况,如果通过 using Base::Base;来声明使用基类的构造函数,但是同时又在派生类中定义相同构造函数,会出现什么结果。
如下示例:
class Base
{
public:
Base(int i):x(i),y(0){}
Base(int i,double j):x(i),y(j){}
Base(int i,double j,const string & str):x(i),y(j),s(str){
cout << "this is Base." << endl;
}
private:
int x;
double y;
string s;
};
class Derived : Base
{
public:
using Base::Base; //声明使用基类的构造函数
Derived(int i,double j,const string & str):Base(i,j,str){
cout << "this is Derived." << endl;
}
};
int main()
{
Derived d1(1);
Derived d2(1,3.2);
Derived d3(1,3.2,"hello");
return 0;
}
输出结果:
this is Base.
this is Derived.
也就是说,如果通过 using Base::Base;来声明使用基类的构造函数,但是同时又在派生类中定义相同构造函数,这时候调用Derived d3(1,3.2,“hello”);, 产生的结果是,会直接调用派生类中的构造函数。
该特性不仅对构造函数有用,对其他同名函数也适用。
class Base
{
public:
void fun(int a){
cout << "call in Base Fun";
}
};
class Derived : Base
{
public:
// using Base::fun;
void fun(int a){
cout << "call in Derived Fun";
}
};
int main()
{
Derived d1;
d1.fun(4);
return 0;
}
以上示例,会输出结果 call in Derived Fun
,因为派生类中的fun函数隐藏了基类中的函数,如果派生类中没有定义fun,那么无法从派生类对象调用基类的fun函数,这时候可以定义 using Base::fun;
然后就可以调用啦。
class Base
{
public:
void fun(int a){
cout << "call in Base Fun";
}
};
class Derived : Base
{
public:
using Base::fun;
};
int main()
{
Derived d1;
d1.fun(4);
return 0;
}