派生类的构造函数:默认情况下,基类的构造函数不被继承,派生类需要定义自己的构造函数。
若不继承基类的构造函数,派生类新增成员需要派生类定义构造函数初始化;继承来的成员自动调用基类构造函数进行初始化;派生类的构造函数需要给基类的构造函数传递参数。
单继承:
派生类只有一个直接基类的情况,是单继承。单继承时,派生类的构造函数只需要给一个直接基类构造函数传递参数。
单继承时的构造函数举例:
#include<iostream>
using namespace std;
class B {
public:
B();
B(int i);
B(B &a);
~B();
void print() const;
private:
int b;
};
B::B() {
b=0;
cout << "B's default constructor called." << endl;
}
B::B(B &a)
{
b = a.b;
cout << "B's fuzhi constructor called" << endl;
}
B::B(int i) {
b=i;
cout << "B's constructor called." << endl;
}
B::~B() {
cout << "B's destructor called." << endl;
}
void B::print() const {
cout << b << endl;
}
class C: public B {
public:
C();
C(B &a, int j);
C(int i, int j);
~C();
void print() const;
private:
int c;
};
C::C() {
c = 0;
cout << "C's default constructor called." << endl;
}
C::C(int i,int j): B(i), c(j){ //C obj(5,6)其实就是调用C的构造函数,
//这里注意B(i)是调用基类B的构造函数,c(j)是指c=j。
cout << "C's constructor called." << endl;
}
C::C(B &a, int j) : B(a), c(j) { //C obj(5,6)其实就是调用C的构造函数,
//这里注意B(i)是调用基类B的构造函数,c(j)是指c=j。
cout << "C's constructor called." << endl;
}
C::~C() {
cout << "C's destructor called." << endl;
}
void C::print() const {
B::print();
cout << c << endl;
}
int main() {
#B a(5);
#C obj(a, 6);
C obj(5, 6);
obj.print();
return 0;
}
多继承及类的组合构造函数举例:
#include <iostream>
using namespace std;
class Base1 {//基类Base1,构造函数有参数
public:
Base1(int i)
{ cout << "Constructing Base1 " << i << endl; }
};
class Base2 {//基类Base2,构造函数有参数
public:
Base2(int j)
{ cout << "Constructing Base2 " << j << endl; }
};
class Base3 {//基类Base3,构造函数无参数
public:
Base3()
{ cout << "Constructing Base3 *" << endl; }
};
class Derived: public Base2, public Base1, public Base3 {
public:
Derived(int a, int b, int c, int d): Base1(a), member2(d), member1(c), Base2(b)
//此处的次序与构造函数的执行次序无关
{ }
private:
Base1 member1;
Base2 member2;
Base3 member3;
};
int main() {
Derived obj(1, 2, 3, 4);
return 0;
}
构造函数的次序与Derived的初始化成员列表次序无关,构造函数的次序根据class Derived: public Base2, public Base1, public Base3 继承循序从左到右初始化,然后根据类的组合从上至下初始化。
虚基类
需要解决的问题:
当派生类从多个基类派生,而这些基类又共同基类,则在访问此共同基类中的成员时,将产生冗余,并有可能因冗余带来不一致性
虚基类声明:
在第一级继承时就要将共同基类设计未虚基类。
主要用来解决多继承时可能发生的对同一基类继承多次而产生的二义性问题。为最远的派生类提供唯一的基类成员,而不重复产生多次复制。
虚基类及其派生类构造函数
建立对象时所指定的类称为最远派生类。
虚基类的成员是由最远派生类的构造函数通过调用虚基类的构造函数进行初始化的。
在整个继承结构中,直接或间接继承虚基类的所有派生类,都必须在构造函数的成员初始化表中为虚基类的构造函数列出参数。如果未列出,则表示调用该虚基类的默认构造函数。
在建立对象时,只有最远派生类的构造函数调用虚基类的构造函数,其他类对虚基类构造函数的调用被忽略。
#include <iostream>
using namespace std;
class Base0 {
public:
Base0(int var) : var0(var) { }
int var0;
void fun0() { cout << "Member of Base0" << endl; }
};
class Base1: virtual public Base0 {
public:
Base1(int var) : Base0(var) { }
int var1;
};
class Base2: virtual public Base0 {
public:
Base2(int var) : Base0(var) { }
int var2;
};
class Derived: public Base1, public Base2 {
public:
Derived(int var) : Base0(var), Base1(var), Base2(var)
{ }
int var;
void fun()
{ cout << "Member of Derived" << endl; }
};
int main() { //程序主函数
Derived d(1);
d.var0 = 2; //直接访问虚基类的数据成员
d.fun0(); //直接访问虚基类的函数成员
return 0;
}