继承-01

本文介绍了C++继承的相关知识,包括继承语法、访问修饰符的使用及作用。阐述了继承的作用,如子类拥有父类成员、可新增方法等。还说明了继承中构造析构调用原则、同名成员变量处理方法,以及不带和带虚函数的单继承、多继承、菱形继承等各种情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

继承语法:
class 派生类名 : 访问修饰符 基类名1, …, 访问修饰符 基类名n
{
成员变量和成员函数
};
访问修饰符: public、protected 或 private,则默认为 private。
public:在类的内部、外部都能使用
protected:在类的内部使用,在继承的子类中使用
private:只能在类的内部,不能在类的外部(包括继承中的子类也不能使用)
(派生类private继承,可以访问基类的函数无法访问成员)

一个派生类继承了所有的基类方法,但下列情况除外:
基类的构造函数、析构函数和拷贝构造函数。
基类的重载运算符。
基类的友元函数。

继承的作用:

  1. 子类拥有父类的所有成员变量和成员函数
  2. 子类可以拥有父类没有的方法和属性
  3. 子类就是一种特殊的父类
  4. 子类对象可以当作父类对象使用

继承中的构造析构调用原则
1、子类对象在创建时会首先调用父类的构造函数
2、父类构造函数执行结束后,执行子类的构造函数
3、当父类的构造函数有参数时,需要在子类的初始化列表中显示调用
4、析构函数调用的先后顺序与构造函数相反

继承中的同名成员变量处理方法

  1. 当子类成员变量与父类成员变量同名时,子类依然从父类继承同名成员
  2. 同名成员存储在内存中的不同位置
  3. 在子类中通过作用域分辨符::进行同名成员区分
    总结:同名成员变量和成员函数通过作用域分辨符进行区分

继承的各种情况

  1. 不带虚函数的单继承
#include "stdafx.h"
#include "iostream"
using namespace std;

class baseClass
{
public:
    baseClass (int a = 1) : base(a){}
    void fun0(){cout << base << endl;}
    int base;
};

class inheritClass : public baseClass
{
public:
    inheritClass  (int a = 2):derive(a){}
    void fun1(){cout << base << endl;}
    int derive;
};

int _tmain(int argc, _TCHAR* argv[])
{
	inheritClass  a;

	return 0;
}

基类和派生类内存中的分布:
在这里插入图片描述
2. 不带虚函数的多继承

#include "stdafx.h"
#include "iostream"
using namespace std;

class baseClass_01
{
public:
    baseClass_01 (int a = 1) : base01(a){}
    void fun0(){cout << base01 << endl;}
    int base01;
};

class baseClass_02
{
public:
    baseClass_02 (int a = 3):base02(a){}
    void fun2(){cout << base02 << endl;}
    int base02;
};

class inheritClass : public baseClass_01,public baseClass_02
{
public:
    inheritClass  (int a = 2):derive(a){}
    void fun1(){cout << derive << endl;}
    int derive;
};

int _tmain(int argc, _TCHAR* argv[])
{
	inheritClass  a(10);
	
	baseClass_01 *pb01 = &a;
	baseClass_02 *pb02 = &a;
	inheritClass* p1 = &a;

	cout << "p1 = " << p1 << "\t pb01 = " << pb01 << "\t pb02 = " << pb02 << endl; 
	return 0;
}

代码运行
在这里插入图片描述
基类和派生类之间转换时会自动寻找起始地址
在这里插入图片描述
3. 不带虚函数的菱形继承

#include "stdafx.h"
#include "iostream"
using namespace std;

class Base
{
public:
    Base (int a = 1):base(a){}
    void fun0(){cout << base << endl;}
    int base;
};

class baseClass_01 : public Base
{
public:
    baseClass_01 (int a = 1) : base01(a){}
    void fun0(){cout << base01 << endl;}
    int base01;
};

class baseClass_02 : public Base
{
public:
    baseClass_02 (int a = 3):base02(a){}
    void fun2(){cout << base02 << endl;}
    int base02;
};

class inheritClass : public baseClass_01,public baseClass_02
{
public:
    inheritClass  (int a = 2):derive(a){}
    void fun1(){cout << derive << endl;}
    int derive;
};

int _tmain(int argc, _TCHAR* argv[])
{
	inheritClass  a(10);
	
	//Base *b = &a; 存在二义性,无法准确确定基类的地址
	baseClass_01 *pb01 = &a;
	baseClass_02 *pb02 = &a;
	inheritClass* p1 = &a;

	cout << " p1 = " << p1 << "\t pb01 = " << pb01 << "\t pb02 = " << pb02 << endl; 
	return 0;
}

在这里插入图片描述
无法将派生类的地址转换成基类Base的地址。由于派生类中存在两个Base基类所以程序无法确定具体哪个地址才是需要的
Base出现两次
【结论】
简单继承(不存在虚函数和虚继承)时,派生类是基类叠加之后的产物。

  1. 带虚函数的单继承
#include "stdafx.h"
#include "iostream"
using namespace std;

class baseClass
{
private:
    int i;
    char c;
public:
    virtual void virt_fun1(){ cout << "baseClass virt_fun1" << endl; }
    virtual void virt_fun2(){ cout << "baseClass virt_fun2" << endl; }
    void comm_fun1(){ cout << "baseClass comm_fun1" << endl; }
    void comm_fun2(){ cout << "baseClass comm_fun2" << endl; }
};

class inheritClass : public baseClass
{
private:
    char c;
public:
    virtual void virt_fun2(){ cout << "inheritClass virt_fun1" << endl; }
    virtual void virt_fun3(){ cout << "inheritClass virt_fun2" << endl; }
    void comm_fun1(){ cout << "inheritClass comm_fun1" << endl; }
    void comm_fun3(){ cout << "inheritClass comm_fun3" << endl; }
};

int _tmain()
{
    inheritClass a;
    a.virt_fun1();
	cout << "------------------------------" << endl;

    baseClass *b = new inheritClass();
    b->virt_fun1();
	b->virt_fun2();	//虚函数,基类指针调用派生类的同名虚函数
    b->comm_fun1();  //普通函数,基类指针调用基类的普通类函数
	cout << "------------------------------" << endl;

    inheritClass *c = (inheritClass*)b;
    c->virt_fun1();
    c->comm_fun1();
    c->comm_fun2();
    c->comm_fun3();
	cout << "------------------------------" << endl;

	cout << " b = " << b << "\n c = " << c << endl;
    return 0;
}

在这里插入图片描述
在这里插入图片描述
【结论】
不管派生类有没有虚函数,基类存在虚函数时派生类中多了一个vfptr(虚函数)指针
派生类和基类存在同名的虚函数时,派生类的虚函数会覆盖基类的同名函数
对于普通同名函数(非虚函数),基类和 派生类分别调用自己的函数
基类有虚函数时,派生类的虚指针位于基类中。派生类中新增的虚函数,追加到第一个基类的虚函数表的后面

  1. 带虚函数的多继承
#include "stdafx.h"
#include "iostream"
using namespace std;

class baseClass_01
{
private:
    int i;
    char c;
public:
    virtual void virt_fun1(){ cout << "baseClass_01 virt_fun1" << endl; }
    virtual void virt_fun2(){ cout << "baseClass_01 virt_fun2" << endl; }
    void comm_fun1(){ cout << "baseClass_01 comm_fun1" << endl; }
    void comm_fun2(){ cout << "baseClass_01 comm_fun2" << endl; }
};

class baseClass_02
{
private:
    int i;
    char c;
public:
    virtual void virt_fun2(){ cout << "baseClass_02 virt_fun2" << endl; }
    virtual void virt_fun3(){ cout << "baseClass_02 virt_fun3" << endl; }
    void comm_fun2(){ cout << "baseClass_02 comm_fun2" << endl; }
    void comm_fun3(){ cout << "baseClass_02 comm_fun3" << endl; }
};

class inheritClass : public baseClass_01, public baseClass_02
{
private:
    char c;
public:
    virtual void virt_fun2(){ cout << "inheritClass virt_fun2" << endl; }
    virtual void virt_fun3(){ cout << "inheritClass virt_fun3" << endl; }
	virtual void virt_fun4(){ cout << "inheritClass virt_fun4" << endl; }
    void comm_fun2(){ cout << "inheritClass comm_fun2" << endl; }
    void comm_fun3(){ cout << "inheritClass comm_fun3" << endl; }
};

int _tmain()
{
    inheritClass a;
    a.virt_fun1();
	cout << "------------------------------" << endl;

    baseClass_01 *b01 = &a;
    b01->virt_fun1();
	b01->virt_fun2();
    b01->comm_fun1();
	cout << "------------------------------" << endl;

    baseClass_02 *b02 = &a;
    b02->virt_fun2();
	b02->virt_fun3();
    b02->comm_fun2();
	cout << "------------------------------" << endl;

    inheritClass *c = (inheritClass*)b01;
    c->virt_fun1();
    c->comm_fun1();
    c->comm_fun2();
    c->comm_fun3();
	cout << "------------------------------" << endl;

	// inheritClass *c = (inheritClass*)b02; 多继承时,是所有基类都能转换成派生类的

	cout << " &a = " << &a << "\n b01 = " << b01 << "\n b02 = " << b02 << "\n c = " << c << endl;
    return 0;
}

在这里插入图片描述
在这里插入图片描述
6. 带虚函数的菱形继承

#include "stdafx.h"
#include "iostream"
using namespace std;

class Base
{
public:
    Base (int a = 1):base(a){}
    virtual void fun0(){cout << base << endl;}
    int base;
};

class baseClass_01 : public Base
{
private:
    int i;
    char c;
public:
    virtual void virt_fun1(){ cout << "baseClass_01 virt_fun1" << endl; }
    virtual void virt_fun2(){ cout << "baseClass_01 virt_fun2" << endl; }
    void comm_fun1(){ cout << "baseClass_01 comm_fun1" << endl; }
    void comm_fun2(){ cout << "baseClass_01 comm_fun2" << endl; }
};

class baseClass_02 : public Base
{
private:
    int i;
    char c;
public:
    virtual void virt_fun2(){ cout << "baseClass_02 virt_fun2" << endl; }
    virtual void virt_fun3(){ cout << "baseClass_02 virt_fun3" << endl; }
    void comm_fun2(){ cout << "baseClass_02 comm_fun2" << endl; }
    void comm_fun3(){ cout << "baseClass_02 comm_fun3" << endl; }
};

class inheritClass : public baseClass_01, public baseClass_02
{
private:
    char c;
public:
    virtual void virt_fun2(){ cout << "inheritClass virt_fun2" << endl; }
    virtual void virt_fun3(){ cout << "inheritClass virt_fun3" << endl; }
	virtual void virt_fun4(){ cout << "inheritClass virt_fun4" << endl; }
    void comm_fun2(){ cout << "inheritClass comm_fun2" << endl; }
    void comm_fun3(){ cout << "inheritClass comm_fun3" << endl; }
};

int _tmain()
{
    inheritClass a;
    a.virt_fun1();
	cout << "------------------------------" << endl;

    baseClass_01 *b01 = &a;
    b01->virt_fun1();
	b01->virt_fun2();
    b01->comm_fun1();
	cout << "------------------------------" << endl;

    baseClass_02 *b02 = &a;
    b02->virt_fun2();
	b02->virt_fun3();
    b02->comm_fun2();
	cout << "------------------------------" << endl;

    inheritClass *c = (inheritClass*)b01;
    c->virt_fun1();
    c->comm_fun1();
    c->comm_fun2();
    c->comm_fun3();
	cout << "------------------------------" << endl;

	// inheritClass *c = (inheritClass*)b02; 多继承时,是所有基类都能转换成派生类的

	cout << " &a = " << &a << "\n b01 = " << b01 << "\n b02 = " << b02 << "\n c = " << c << endl;
    return 0;
}

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值