第七章(中)派生类

派生类的构造和析构

派生类的构造函数

默认情况下,基类的构造函数不被继承,派生类需要自己定义自己的构造函数(还需要传参数给基类去初始化)
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;
}

虚基类

为避免二义性和冗余,我们可以使用虚基类,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gylagyl97

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值