派生类的构造和析构
派生类的构造函数
默认情况下,基类的构造函数不被继承,派生类需要自己定义自己的构造函数(还需要传参数给基类去初始化)
c++11规定:可以用using语句继承基类的构造函数。(适用于派生类很少或者没有新增成员)
但是只能初始化从基类继承的成员。
using B::B;
如果派生类需要对自己新增的成员制定参数初始化,最好就自己写构造函数,不继承基类的构造函数。所以:
那些从基类继承过来的成员,到底怎么进行初始化呢?
最后一句话是关键。
单继承:
#include<iostream>
using namespace std;
class B {
public:
B();
B(int i);
~B();
void print() const;
private:
int b;
};
B::B() {
b=0;
cout << "B's default 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(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){
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() {
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;
}
派生类的复制构造函数
派生类中有新增成员时,派生类的复制工作是分成两部分的:
基类继承过来的成员由积累的复制构造函数完成,派生类自己新增的成员复制构造,由派生类自己的复制构造函数完成。(也有传参数的问题)
派生类的析构函数
析构函数和构造函数一样,都不能被继承,如果需要,需要自己定义析构函数。
访问从基类继承的成员
基类的成员继承到派生类中之后,访问的时候有无特殊需要注意的问题?
例7-6 多继承同名隐藏举例
#include <iostream>
using namespace std;
class Base1 {
public:
int var;
void fun() { cout << "Member of Base1" << endl; }
};
class Base2 {
public:
int var;
void fun() { cout << "Member of Base2" << endl; }
};
class Derived: public Base1, public Base2 {
public:
int var;
void fun() { cout << "Member of Derived" << endl; }
};
int main() {
Derived d;
Derived *p = &d;
//访问Derived类成员
d.var = 1;
d.fun();
//访问Base1基类成员
d.Base1::var = 2;
d.Base1::fun();
//访问Base2基类成员
p->Base2::var = 3;
p->Base2::fun();
return 0;
}
多继承时:
//7_7.cpp
#include <iostream>
using namespace std;
class Base0 { //定义基类Base0
public:
int var0;
void fun0() { cout << "Member of Base0" << endl; }
};
class Base1: public Base0 { //定义派生类Base1
public: //新增外部接口
int var1;
};
class Base2: public Base0 { //定义派生类Base2
public: //新增外部接口
int var2;
};
例7-7 多继承时的二义性和冗余问题
class Derived: public Base1, public Base2 {
public:
int var;
void fun()
{ cout << "Member of Derived" << endl; }
};
int main() { //程序主函数
Derived d;
d.Base1::var0 = 2;
d.Base1::fun0();
d.Base2::var0 = 3;
d.Base2::fun0();
return 0;
}
虚基类
为避免二义性和冗余,我们可以使用虚基类,