C++继承中的构造和析构
1,构造:对象在创建的后所要做的一系列初始化的工作;
析构:对象在摧毁之前所要做的一系列清理工作;
2,思考:
1,子类中如何初始化父类成员?
1,对于继承而言,子类可以获得父类的代码,可以获得父类中的成员变量,成员变量从父类中传递到子类,那么子类对象在创建的时候如何初始化从父类中继承的成员变量呢?
2,父类构造函数和子类构造函数有有什么关系?
3,子类对象的构造:
1,子类中可以定义构造函数;
1,子类中定义的新的构造函数,对于子类对象创建的时候必须完成一系列的初始化工作,这些初始化工作包括初始化继承而来的成员,第一种方式直接对他们进行赋值或者直接将他们写到初始化列表中去进行初始化,第二种方式更直接,在子类构造的时候我们调用父类构造函数进行初始化;
2,这就是子类构造函数可以用来初始化父类成员的两种方式;
2,子类构造函数:
1,必须对继承而来的成员进行初始化;
1,直接通过初始化列表或者赋值的方式进行初始化;
1,有可能从父类中继承了 private 成员,因此直接来进行赋值或初始化根本就是行不通的,因此这个时候只能通过父类的构造函数来进行初始化的工作;
2,调用父类构造函数进行初始化;
3,父类构造函数在子类中的调用方式;
1,默认调用:
1,子类对象在创建的时候会自动的调用父类的构造函数;
2,适用于无参构造函数和使用默认参数的构造函数;
1,对于需要参数的构造函数来说,默认的调用方式是行不通的,必须显示调用;
2,显示调用:
1,通过初始化列表进行调用;
1,只能在初始化列表中调用;
2,适用于所有父类构造函数;
3,父类构造函数的调用:
1,代码示例:
- class Child : public Parent
- {
- Public:
- Child() /* 隐式调用 */
- {
- Cout << “Child()” << endl;
- }
- Child(string s) : Parent(“Parameter to Parent”) /* 显示调用 */
- {
- Cout << “Child() : “ << s << endl;
- }
- };
4,子类的构造初探编程实验:
- #include <iostream>
- #include <string>
- using namespace std;
- class Parent
- {
- public:
- Parent()
- {
- cout << "Parent()" << endl;
- }
- Parent(string s)
- {
- cout << "Parent(string s) : " << s << endl;
- }
- };
- class Child : public Parent
- {
- public:
- Child() // 隐式调用父类构造函数中的无参或默认初始值构造函数
- {
- cout << "Child()" << endl;
- }
- Child(string s) // 隐式调用父类构造函数中的无参或默认初始值构造函数;
- {
- cout << "Child(string s) : " << s << endl;
- }
- Child(string s): Parent(s) // 显示调用父类构造函数;
- {
- cout << "Child(string s) : " << s << endl;
- }
- };
- int main()
- {
- Child c; // 调用父类无参构造函数,然后调用子类无参构造函数;
- Child cc("cc"); // 调用父类有参构造函数,然后调用子类构造函数;
- return ;
- }
1,子类和父类的构造函数的调用都严格按照重载规则调用;
5,子类对象的构造:
1,构造规则:
1,子类对象在创建时会首先调用父类的构造函数(要以子类构造函数调用为依据);
2,先执行父类构造函数再执行子类构造函数;
3,父类构造函数可以被隐式调用或者显示调用;
2,对象创建时构造函数的调用顺序:
1,调用父类的构造函数;
2,调用成员变量的构造函数;
3,调用类自身的构造函数;
4,口诀:
1,先父母(调到最上的父母为止),后客人(按照成员变量申明的顺序),再自己;
2,非常实用;
3,子类构造深度解析编程实验:
- #include <iostream>
- #include <string>
- using namespace std;
- class Object
- {
- public:
- Object(string s)
- {
- cout << "Object(string s) : " << s << endl;
- }
- };
- class Parent : public Object
- {
- public:
- Parent() : Object("Default") // 必须显示调用
- {
- cout << "Parent()" << endl;
- }
- Parent(string s) : Object(s) // 必须显示调用
- {
- cout << "Parent(string s) : " << s << endl;
- }
- };
- class Child : public Parent
- {
- Object mO1; // 组合关系,默认构造函数和有参数构造函数,这里必须显示调用
- Object mO2;
- public:
- Child() : mO1("Default 1"), mO2("Default 2")
- {
- cout << "Child()" << endl;
- }
- Child(string s) : Parent(s), mO1(s + ""), mO2(s + "") // 父母和成员客人的区别在于父母构造函数直接调用,客人构造函数通过对象调用;
- {
- cout << "Child(string s) : " << s << endl;
- }
- };
- int main()
- {
- Child cc("cc");
- // cc output:
- // Object(string s) : cc 父母
- // Parent(string s) : cc 父母
- // Object(string s) : cc 1 客人
- // Object(string s) : cc 2 客人
- // Child(string s) : cc 自己
- return ;
- }
6,子类对象的析构:
1,析构函数的调用顺序与构造函数相反:
1,执行自身的析构函数;
2,执行成员变量的析构函数;
3,执行父类的析构函数;
2,对象的析构编程实验:
- #include <iostream>
- #include <string>
- using namespace std;
- class Object
- {
- string ms; // 为了验证析构函数的输出,定义了这个成员变量来传递值,因为构造函数可以由外界传入值,但是析构函数没有参数,是不可以由完结传入值的;
- public:
- Object(string s)
- {
- cout << "Object(string s) : " << s << endl;
- ms = s;
- }
- ~Object()
- {
- cout << "~Object() : " << ms << endl;
- }
- };
- class Parent : public Object
- {
- string ms;
- public:
- Parent() : Object("Default")
- {
- cout << "Parent()" << endl;
- ms = "Default";
- }
- Parent(string s) : Object(s)
- {
- cout << "Parent(string s) : " << s << endl;
- ms = s;
- }
- ~Parent()
- {
- cout << "~Parent() : " << ms << endl;
- }
- };
- class Child : public Parent
- {
- Object mO1;
- Object mO2;
- string ms;
- public:
- Child() : mO1("Default 1"), mO2("Default 2")
- {
- cout << "Child()" << endl;
- ms = "Default";
- }
- Child(string s) : Parent(s), mO1(s + ""), mO2(s + "")
- {
- cout << "Child(string s) : " << s << endl;
- ms = s;
- }
- ~Child()
- {
- cout << "~Child() " << ms << endl;
- }
- };
- int main()
- {
- Child cc("cc");
- cout << endl;
- return ;
- }
7,小结:
1,子类对象在创建时需要调用父类构造函数进行初始化;
2,先执行父类构造函数然后执行成员的析构函数;
3,父类构造函数显示调用需要在初始化列表中进行;
4,子类对象在销毁时需要调用父类析构函数进行清理;
5,析构顺序与构造顺序对称相反;
1,先自己,后客人,再父母;
C++继承中的构造和析构的更多相关文章
- C++ 类的继承三(继承中的构造与析构)
//继承中的构造与析构 #include<iostream> using namespace std; /* 继承中的构造析构调用原则 1.子类对象在创建时会首先调用父类的构造函数 2.父 ...
- C++学习笔记-继承中的构造与析构
C++存在构造函数与析构函数,继承中也存在构造和析构函数.继承中的构造和析构函数与普通的构造析构有细微差别. 赋值兼容性原则 #include "iostream" using n ...
- C++语法小记---继承中的构造和析构顺序
继承中构造和析构的顺序 先父母,后客人,最后自己 静态变量和全局变量在最开始 析构和构造的顺序完全相反 #include <iostream> #include <string> ...
- Swift难点-继承中的构造规则实例具体解释
关于继承中的构造规则是一个难点. 假设有问题,请留言问我. 我的Swift新手教程专栏 http://blog.csdn.net/column/details/swfitexperience.html ...
- C++ //继承中构造和析构顺序
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 class Base 6 { 7 pu ...
- c++:空构造空析构的益处之一
项目开发过程中发现一个问题,有段代码,一个动态库的cpp代码里不包含头文件中类的空构造空析构实现,就会出现编译出的动态库依赖项少了很多.而添加后则多了好几个依赖项.下面看例子: ##a.h class ...
- C++浅析——继承类中构造和析构顺序
先看测试代码,CTEST 继承自CBase,并包含一个CMember成员对象: static int nIndex = 1; class CMember { public: CMember() { p ...
- Effective C++_笔记_条款09_绝不在构造和析构过程中调用virtual函数
(整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 为方便采用书上的例子,先提出问题,在说解决方案. 1 问题 1: ...
- c++中的构造(包括移动),赋值(包括移动),析构详解
这五种操作:构造(包括移动),赋值(包括移动),析构其实就是定义了对一个对象进行构造,赋值,析构时的行为.理解这些行为并不复杂,复杂的是理解在继承下这些行为的表现.需要注意的是他们并不会被继承(传统意 ...
随机推荐
- MyBatis 配置/注解 SQL CRUD 经典解决方案(2019.08.15持续更新)
本文旨在记录使用各位大神的经典解决方案. 2019.08.14 更新 Mybatis saveOrUpdate SelectKey非主键的使用 MyBatis实现SaveOrUpdate mybati ...
- spring(五):spring中Aware接口的使用
spring中自定义组件需要使用spring的底层组件时,可以通过自定义组件实现相关XxxAware接口,重写其中的方法进而实现 例如:自定义一个组件,该组件中需要使用ApplicationConte ...
- 常见前端面试题http部分
1.常见http状态码 100 Continue 继续,一般在发送post请求时,已发送了http header之后服务端将返回此信息,表示确认,之后发送具体参数信息 200 OK 正常返回信息 20 ...
- vue,一路走来(2)--路由vue-router
安装 Mint UI cnpm install mint-ui --save 如果你的项目会用到 Mint UI 里较多的组件,最简单的方法就是把它们全部引入.此时需要在入口文件 main.js 中: ...
- Java8 stream基础
List<Integer> list = new ArrayList<Integer>(); list.add(2); list.add(4); list.add(0); li ...
- 【串线篇】sql映射文件-分布查询(上)association 1-1
1.场景 1把钥匙带1把锁 JavaBean:private Lock lock;//当前钥匙能开哪个锁: 1). interface KeyDao: public Key getKeyByIdSim ...
- python模块之numpy,pandas基本用法
numpy: 是 Python 的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库简单来说:就是支持一维数组和多维数组的创建和操作,并有丰富的函数库. 直接看例子 ...
- SpringBoot---注册Servlet,Filter,Listener
1.概述 1.1.当使用 内嵌的Servlet容器(Tomcat.Jetty等)时,将Servlet,Filter,Listener 注册到Servlet容器的方法: 1.1.1.直接注册Bean ...
- boost unordered
Boost.Unordered provides the classes boost::unordered_set, boost::unordered_multiset, boost::unorder ...
- DELPHI FIREDAC SQLITE不能插入"&"符号
在查询数据里,发现数据不匹配,检查发现少了"&"符号,试了添加转义字符等方式还是不行,经过摸索发现解决办法: 设置ResourceOptions.MacroCreate 和 ...