C++基础13-类和对象之继承2

总结:

1、子类对象可以当做父类对象使用
2、子类对象可以直接赋值给父类对象
3、子类对象能够直接初始化父类对象
4、父类指针可以直接指向子类对象
5、凡是继承过来的属性和函数都可以在子类中用this->  进行访问
6、默认构造函数并不会初始化数据成员
7、如果子类数据成员和父类数据成员名称相同。在子类用利用:: 访问父类数据成员,this-> 默认为子类数据成员

8、构造函数和析构函数不会被继承

一、类型兼容性规则

类型兼容规则是指在需要基类对象的任何地方,都可以使用公有派生类的对象来替代。通过公有继承,派生类得到了基类中构造函数、析构函数之外的所有成员。这样,公有派生类实际就具备了基类的所有功能,凡是基类能解决的问题,公有派生类都可以解决。

类型兼容规则中所指的替代包括以下情况:

             <1>子类对象可以当作父类对象使用

             <2>子类对象可以直接赋值给父类对象

             <3>子类对象可以直接初始化父类对象

             <4>父类指针可以直接指向子类对象

             <5>父类引用可以直接引用子类对象

继承模型:

在子类对象构造时,需要调用父类构造函数对其继承得来的成员进行初始化.

在子类对象析构时,需要调用父类析构函数对其继承得来的成员进行清理.

二、继承中构造析构调用原则

        1、子类对象在创建时会首先调用父类的构造函数

        2、父类构造函数执行结束后,执行子类的构造函数

        3、当父类的构造函数有参数时,需要在子类的初始化列表中显示调用

        4、析构函数调用的先后顺序与构造函数相反

总原则:

                      先构造父类,再构造成员变量、最后构造自己

                      先析构自己,在析构成员变量、最后析构父类

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

1、当子类成员变量与父类成员变量同名时 ,子类依然从父类继承同名成员

2、在子类中通过作用域分辨符::进行同名成员区分(在派生类中使用基类的同名成员,显式地使用类名限定符)

注:同名成员存储在内存中的不同位置

四、派生类中的static关键字

1、基类定义的静态成员,将被所有派生类共享

2、根据静态成员自身的访问特性和派生类的继承方式,在类层次体系中具有不同的访问性质 (遵守派生类的访问控制)

3、 派生类中访问静态成员,用以下形式显式说明:

                                      类名 :: 成员

       或通过对象访问      对象名 . 成员

示例:

1、类的兼容性规则

#if 1
#include<iostream>
using namespace std;class Parent {
public:void printP() {cout << "a:" << this->a << endl;}int a;
};
class Child :public Parent {
public:/*void printP() {cout << "b:" << this->b << endl;}*/void printC() {cout << "b:" << this->b << endl;}int b;
};
void test01() {Parent *p = new Child;p->printP();  //子类和父类都有printP函数时,调用父类的成员函数
}
//子类对象可以当做父类对象使用
//子类对象可以直接赋值给父类对象
//子类对象能够直接初始化父类对象
void test02() {Parent p;  //父类空间小//Child c = p; //子类空间大于父类,不能够全部初始化,所以报错Child c;Parent p = c;  //c对象占用空间>=p对象占用空间 //能够填充可以通过编译//子类对象能够直接初始化父类对象c.printP();  //c能够当做父类p来使用}
//父类指针可以直接指向子类对象
//好处:
void test03() {Parent *pp = NULL;  //父类指针Child *cp = NULL;   //子类指针Parent p;  //父类对象Child c;   //子类对象cp = &c;//cp = &p;  子类指针指向父类对象 错误 子类指针访问范围大于父类对象的范围//原来cp的访问权限为cp->a,cp->b,cp->printP.cp->printC//cp指向p时,cp的访问权限只能为cp->a,cp->printP//会访问越界pp = &p;pp = &c;  //通过编译 父类指针指向子类对象//原来cp的访问权限为pp->a; pp->printP//pp指向c时,cp的访问权限扔为pp->a; pp->printP//c内存布局能够满足父类指针的全部需求  可以用一个儿子的对象地址给父类指针赋值}
int main() {return 0;
}
#endif

2、构造函数和析构函数

#if 0
#include<iostream>
using namespace std;
//在调用子类的构造函数时  一定会调用父类的构造函数
//父类先构造,子类再构造
//析构和构造顺序相反
class Parent {
public:Parent() {cout << "Parent()... " << endl;a = 0;}Parent(int a) {cout << "Parent(int a)..." << endl;this->a = a;}int a;~Parent() {cout << "~Parent()..." << endl;}
};
class Child :public Parent {
public://在调用子类的构造函数时  编译器会默认调用父类无参构造
#if 0Child(int a,int b) {cout << "Child(int a,int b)..." << endl;this->a = a;this->b = b;}
#endif//显示调用父类有参构造Child(int a ,int b):Parent(a){cout << "Child(int a,int b)..." << endl;this->b = b;}~Child() {cout << "~Child()... " << endl;}void printC() {cout << "b=" << b << endl;}int b;
};//在调用子类时 编译器会默认调用父类无参构造 
void test01() {Child c(10, 20);c.printC();
}
/*
Parent()...
Child(int a,int b)...
b=20
~Child()...
~Parent()...
*/
//显示调用父类有参构造
void test02() {Child c(10, 20);c.printC();
}
/*
Parent(int a)...
Child(int a,int b)...
b=20
~Child()...
~Parent()...
*/
int main() {test01();return 0;
}
#endif

3、子类和父类成员重名

#if 0
#include<iostream>
using namespace std;
#if 0
class Parent {
public:Parent() {cout << "Parent() " << endl;this->a = 0;}Parent(int a) {cout << "Parent(int a) " << endl;this->a = a;}~Parent() {cout << "析构父类a:" << this->a << endl;}int a;
};
class Child :public Parent {
public:int a;Child(int a) {cout << "Child(int a)" << endl;this->a = a;}~Child() {cout << "析构子类a:" << this->a << endl;}
};void test01() {Child c(2);
}
/*
Parent()
Child(int a)
析构子类a:2
析构父类a:0
*/
#endif
#if 0
class Parent {
public:Parent(int a) {cout << "Parent(int a) " << endl;this->a = a;}~Parent() {cout << "析构父类a:" << this->a << endl;}int a;
};
class Child :public Parent {
public:int a;Child(int p_a,int c_a):Parent(p_a){cout << "Child(int a)" << endl;this->a = c_a;}~Child() {cout << "析构子类a:" << this->a << endl;}void print() {cout << "父类a:"<<Parent::a << endl;cout <<"子类a:" <<this->a << endl;  //子类的a}
};void test01() {Child c(2,3);c.print();
}
/*
Parent(int a)
Child(int a)
父类a:2
子类a:3
析构子类a:3
析构父类a:2
*/
#endif
//子类和父类函数名相同调用 
class Parent {
public:Parent(int a) {cout << "Parent(int a) " << endl;this->a = a;}void print() {cout << "父类print" <<  endl;}~Parent() {cout << "析构父类a:" << this->a << endl;}int a;
};
class Child :public Parent {
public:int a;Child(int p_a, int c_a) :Parent(p_a) {cout << "Child(int a)" << endl;this->a = c_a;}~Child() {cout << "析构子类a:" << this->a << endl;}void print() {cout << "子类print" << endl;  //子类的a}
};void test01() {Parent p(1);p.print();cout << "------" << endl;Child c(2, 3);c.Parent::print();c.print();	
}
/*
Parent(int a)
父类print
------
Parent(int a)
Child(int a)
父类print
子类print
析构子类a:3
析构父类a:2
析构父类a:1
*/
int main() {test01();return 0;
}
#endif

4、继承中的static成员

#if 1
#include<iostream>
using namespace std;
#if 0
class A {
public:static int a;
private:
};
int A::a = 0;  //静态成员变量 初始化void test01()
{A a1;A a2;cout << a1.a << endl;cout << a2.a << endl;a1.a = 300;cout << a1.a << endl;cout << a2.a << endl;
}
/*
0
0
300
300
*/
#endifclass A {
public:static int a;
private:
};
class B :public A {
public:
private:
};
int A::a = 0;  //静态成员变量 初始化void test01()
{A a1;A a2;cout << a1.a << endl;cout << a2.a << endl;a1.a = 300;cout << a1.a << endl;cout << a2.a << endl;B b1;B b2;cout << b1.a << endl;cout << b2.a << endl;A::a = 400;cout << b1.a << endl;cout << b2.a << endl;
}
/*
0
0
300
300
300
300
400
400
*/
int main() {test01();return 0;
}
#endif

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/567864.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux内核 块驱动程序,linux – 为什么内核使用默认的块驱动程序而不是我的驱动程序代码?...

我写了一个块驱动程序,它创建了一个虚拟块设备(sbd0).我为该块设备注册了所有设备操作:(请参阅2.6.32内核源代码中的include /linux / blkdev.h)static struct block_device_operations sbd_ops {.owner THIS_MODULE,.open sbd_open,.release sbd_close,.ioctl sbd_ioctl,…

C++基础14-类和对象之多继承与虚继承

多继承&#xff1a;一个类有多个直接基类的继承关系称为多继承 总结&#xff1a; 1、一般将具有菱形样式继承方式的某些类声明为虚继承 3、虚继承的主要目的是为了防止二义性 2、虚继承就是在继承方式前加virtual 如果一个派生类从多个基类派生&#xff0c;而这些基类又有一…

linux系统安装ntp,CentOS下NTP安装配置

安装yum install ntp配置文件 /etc/ntp.confrestrict default kod nomodifynotrap nopeer noqueryrestrict -6 default kod nomodify notrap nopeer noqueryrestrict 127.0.0.1restrict -6 ::1# 用restrict控管权限# nomodify - 用户端不能更改ntp服务器的时间参数# noquery - …

C++基础15-类和对象之多态

总结&#xff1a; 1、在父类中申明虚函数时&#xff0c;一般情况下在子类中也申明&#xff08;便于读代码&#xff09; 一、赋值兼容 赋值兼容规则是指在需要基类对象的任何地方都可以使用公有派生类的对象来替代。 赋值兼容是一种默认行为,不需要任何的显示的转化步骤。 …

傲云浏览器linux,Centos7安装部署zabbix监控软件

目录部署监控服务器部署监控服务器Zabbix ServerWeb页面验证设置部署监控服务器一、安装LNMP环境Zabbix监控管理控制台需要通过Web页面展示出来&#xff0c;并且还需要使用MySQL来存储数据&#xff0c;因此需要先为Zabbix准备基础LNMP环境。1. wget下载官网Nginxwget http://ng…

C++基础16-类和对象之联编,重写,虚析构

1、静态联编和动态联编 1、联编是指一个程序模块、代码之间互相关联的过程。 2、静态联编&#xff08;sta5c binding&#xff09;&#xff0c;是程序的匹配、连接在编译阶段实现&#xff0c;也称为早期匹配。重载函数使用静态联编。 3、动态联编是指程序联编推迟到运行时…

c语言环境变量的作用,C语言获取系统环境变量

C语言获取系统环境变量可以通过如下代码实现.#include #include char *platform(){//获取系统变量信息char *ret;extern char **environ;char **env environ;//打印系统变量信息/*while(*env){//puts(*env);env;}*/ret getenv("OS"); //for windows_ntif(NULL ! re…

C++基础17-纯虚函数和抽象类

总结&#xff1a; 1,含有纯虚函数的类,称为抽象基类,不可实列化。即不能创建对象,存在 的意义就是被继承,提供族类的公共接口。 2,纯虚函数只有声明,没有实现,被“初始化”为 0。 3,如果一个类中声明了纯虚函数,而在派生类中没有对该函数定义,则该虚函数在派生类中仍然为纯…

c语言wpf99乘法表,使用JSP输出九九乘法表

R数据实战vehicles--1新建项目vehicles-project 数据文件vehicles.csv与varlabels.txt放在项目文件中【CSS3】---颜色RGBA及渐变色颜色之RGBA RGB是一种色彩标准,是由红(R).绿(G).蓝(B)的变化以及相互叠加来得到各式各样的颜色.RGBA是在RGB的基础上增加了控制alpha透明度的参数…

C++基础18-抽象类-电脑组装练习

01电脑组装me.cpp 需要实现所有的虚函数&#xff0c;不台灵活。架构函数无法写&#xff0c;设计不够成熟 #if 1 #include<iostream> using namespace std; class Computer { public:virtual void caculate() 0;virtual void display() 0;virtual void storage() 0; …

以串结构存储c语言版,数据结构C语言版 串的块链存储表示和实现

《数据结构C语言版 串的块链存储表示和实现》由会员分享&#xff0c;可在线阅读&#xff0c;更多相关《数据结构C语言版 串的块链存储表示和实现(13页珍藏版)》请在人人文库网上搜索。1、*数据结构C语言版 串的块链存储表示和实现P78编译环境&#xff1a;Dev-C 4.9.9.2日期&…

mysql索引创建及使用注意事项

总结&#xff1a; 1、在使用索引时&#xff0c;一般情况下不建议使用like操作。如果使用&#xff0c;则%放在后面。否则不会使用索引。like ‘%abd%’不会使用索引,而like ‘aaa%’可以使用索引.&#xff08;最左缀原则&#xff09; 2、单列索引的使用&#xff1a; 《1》 只…

mulitpartfile怎么接收不到值_和平精英信号接收区和信号值是什么?信号值怎么恢复...

[闽南网]和平精英公测开启&#xff0c;和平精英与刺激战场有什么不同呢&#xff1f;今天小编就为大家带来了信号值详解&#xff01;各位玩家千万不要错过呀&#xff01;信号值详解信号接收区和信号值是什么&#xff0c;对选手有什么影响&#xff1f;在游戏战斗界面中&#xff0…

c语言编程判断素数的函数,【面试题】C语言:实现一个函数,判断一个数是不是素数。...

#include#include#includeint prime(int num){int k 0;int i 0;k sqrt(num);for (i 2; i < k; i) /*不满足循环条件时即均不可被整除&#xff0c;不是素数*/{if (num%i 0){return 0;}}return -1;}int main(){int num 0;int ret 0;printf("please input the nu…

Linux命令 umask,chmod使用

一、文件权限详解 1、文件权限介绍 在linux中的每一个文件或目录都包含有访问权限&#xff0c;这些访问权限决定了谁能访问和如何访问这些文件和目录。通过设定权限可以从以下三种访问方式限制访问权限&#xff1a;只允许用户自己访问&#xff1b;允许一个预先指定的用户组中…

python启动c语言gdb,使用gdb调试python程序

游戏服务器菜鸟之C&num;初探三游戏服务在经过上述2番折腾之后,最后决定使用TCP进行通信,所以在一次进行重构 主要重构的要点 1.将过来的HTPP请求,重构为TCP请求: 2.使用组件FluenScheduler进行怪物的定时刷新,和定时 ...Windows环境下的NodeJS&plus;NPM&plus;Bower…

制备pdms膜的方法_船体用钢板基底超疏水表面的制备和性能

鲨鱼皮具有神奇的微纳双层结构&#xff0c;其微米级肋条状结构在水中的整流效果可减小水的阻力。纳米级刺状突起或刚毛具有疏水特性&#xff0c;使植物抱子很难附着其上&#xff0c;海藻等植物也不能在其表面生长&#xff3b;1,2&#xff3d;。这种微纳结构及其疏水性的共同作用…

递归题型解析

#include<iostream> using namespace std; int foo(int n) {if (n < 1)return n;return (foo(n - 1) foo(n - 2)); } int main() {printf("%d\n", foo(5));return 0; } 解析&#xff1a; foo(5)foo(4)f00(3)foo(3)foo(2)foo(3)2foo(3)foo(2)2(foo(2)foo(1…

64位c语言调用32位glibc,glibc fclose源代码阅读及伪造_IO_FILE利用fclose实现任意地址执行...

简介最近学习了一下_IO_FILE的利用&#xff0c;刚好在pwnable.tw上碰到一道相关的题目。拿来做了一下&#xff0c;遇到了一些困难&#xff0c;不过顺利解决了&#xff0c;顺便读了一波相关源码&#xff0c;对_IO_FILE有了更深的理解。文章分为三部分&#xff0c;分别是利用原理…

戴尔笔记本电脑开机黑屏怎么办_戴尔笔记本电脑充不进电怎么办

笔记本电脑电池充不进电要怎么办呢&#xff1f;笔记本电脑之所以这么受欢迎&#xff0c;是因为笔记本有配备电池&#xff0c;能够在没有电源的情况下使用五六个小时。而电池的电用光后&#xff0c;就需要进行充电。不过有些用户反映说&#xff0c;自己的电池充不进电&#xff0…