C++入门Step16【类的构造与析构函数】
类的构造函数与析构函数:
- 类的构造函数的重载:
在上一节中,函数的重载与默认参数,都是用的普通的函数,实际上在类的构造函数和成员函数上面一样适用。带参数的构造函数,其中就有多个带参数的构造函数,实际上就是实现了构造函数的重载。
构造函数中的参数初始化表:
用这种方式实现的构造函数体积小,代码显得更简洁,显得比较
,举个栗子:class CStudent {public:char name[50];char sex;int num;int age;CStudent(char* pname, char t_sex, int t_num, int t_age); };CStudent::CStudent(char* pname, char t_sex, int t_num, int t_age) :sex(t_sex), num(t_num), age(t_age) {strcpy(name, pname); }
析构函数:
基本介绍:
析构函数也是一个在类中跟构造函数类似的特殊功能的成员函数。只不过它的作用是与构造函数相反,是在对象的生命周期结束的时候会被自动调用的。在C++中析构函数的名字跟类名相同,并且前面带上一个取反的符号
~
,表达的意思也就是跟构造函数的过程相反。默认情况下,如果类的设计者没有自己定义析构函数,那么编译器会自动为该类生成一个默认的析构函数,只不过函数体是空的,也就是什么都没做。所以,如果需要在对象被删除的时候做一些操作的话,那么就得自己定义析构函数。
会被自动调用析构函数几种情况:
①. 如果在一个函数中定义了一个局部变量的对象,那么当这个函数执行结束时也就是该变量对象生命周期结束的时候,所以析构函数会被自动调用;
②. 全局变量或者static类型的变量,他们的生命周期一般是在程序退出的时候,这时候该对象的析构函数才会被调用;
③. 如果是用new操作符动态的创建了一个对象,只有当用delete进行释放该对象的时候,析构函数才会被调用;析构函数的作用:
首先,必须明确:析构函数与对象,构造函数与对象的先后或因果关系:
a. 构造函数:是用来初始化刚创建出的对象的,并非是构造函数创建了对象;
b. 析构函数:是当对象被删除时被自动调用的,用来做一些对象被删除之前的清理工作,而并非是析构函数删除了对象;只要对象的生命周期结束,那么程序就会自动执行析构函数来完成这个工作的。
析构函数的特点:
析构函数不返回任何值,没有函数类型,也没有任何函数的参数。由于上面这些特点,所以析构函数不能被重载,所以说一个类可以有多个构造函数,但只能有一个析构函数。析构函数之举个栗子:
class CStudent {public:char name[50];char sex;int num;int age;CStudent(); //构造函数声明~CStudent(); //析构函数声明 };CStudent::CStudent() //构造函数定义 {std::cout<< "1.构造函数被调用" <<std::endl; }CStudent::~CStudent() //析构函数定义 {std::cout<< "1.析构函数被调用" <<std::endl; }int main() {CStudent stud; //实例化对象studreturn 0; }
实际编程中经常用到的构造和析构过程:(动态申请和释放内存实现)
//头文件:inc.h class Student { private: char* p_name; char* p_No; int age; bool sex; public: void set_nnas(); void print_imt(); Student(); explicit Student(char* t_name, char* t_No, int t_age, bool sex);~Student(); };//类函数实现文件:export.cpp #include <iostream> #include <cstring> #include "inc.h" #define LEN 8 #define DFT "default" #define HINT1 "1.构造函数被成功调用" #define HINT2 "2.析构函数被成功调用"void Student::set_nnas() {std::cout << "Please enter the \"name,num,age,sex\" successively\r" <<std::endl;std::cin >> p_name >> p_No >> age >>sex; }void Student::print_imt() {std::cout << "The information of student:\n\tName: " << p_name <<"\n\tNo.: "<<p_No<<"\n\tAge: "<<age<<"\n\tSex: "<<sex<<std::endl; }Student::~Student() {delete [] p_name;delete [] p_No;std::cout<< HINT2 <<std::endl; }Student::Student(char* t_name, char* t_No, int t_age, bool t_sex):age(t_age),sex(t_sex) {int ne_len = std::strlen(t_name),no_len = std::strlen(t_No);p_name = new char[ne_len+1];memset(p_name,0,ne_len+1);strcpy(p_name,t_name);p_No = new char[no_len+1];memset(p_No,0,no_len+1);strcpy(p_No,t_No);std::cout<< HINT1 <<std::endl; }Student::Student() {p_name = new char [LEN];memset(p_name, 0, LEN);strcpy(p_name,DFT);p_No = new char [LEN];memset(p_No, 0, LEN);strcpy(p_No,DFT);age = 0;sex = true;std::cout<< HINT1 <<std::endl; }//主函数:main.h #include <iostream> #include "inc.h" using namespace std;int main() {Student* Wl01;Wl01 = new Student;Wl01->print_imt();delete Wl01;cout<<endl;Student *Wl02;Wl02 = new Student("WangLong", "1110618014038", 21, true);Wl02->print_imt();delete Wl02;return 0; }
reflect on it :
class CStudent{public:char* name;char sex;int no;int age;CStudent(char* t_name, char t_sex, int t_no, int t_age){name = t_name;sex = t_sex;no = t_no;age = t_age;}~CStudent(){cout<<name<<"\t\t被释放"<<endl;} }; //有这么个函数: void test_xiGou() {CStudent zhang_san("zhangsan", 'f', 1001, 21);CStudent li_si("lisi", 'm', 1002, 22);CStudent wang_wu("wangwu", 'm', 1003, 23); } //在 test_xiGou 函数中依次定义了三个局部变量的对象:zhang_san、li_si、wang_wu,那么当离开 test_xiGou 函数之后,这三个对象的析构顺序又是怎么样的呢?int main() {test_xiGou();return 0; }
结果背后的原因:参考压栈与出栈规则(先进后出)
C++入门Step16【类的构造与析构函数】相关推荐
- 转:Delphi2010新发现-类的构造和析构函数功能
Delphi2010发布了. 虽然凭着对Delphi的热爱第一时间就安装了,但是现在可能是年纪大了,对新事物缺乏兴趣了.一直都没有仔细研究. 今天有点时间试了一下新功能. 本来C#和Delphi.NE ...
- 《C#零基础入门之百识百例》(四十三)类的构造和析构函数 -- 模拟用户注册
C#零基础入门 类和对象 -- 构造和析构函数 -- 模拟用户注册 前言 一,构造函数 1.1 实例化构造函数 1.2 this访问器 二,析构函数 1.1 概念介绍 2.2 代码示例 三,实例练习 ...
- 5、继承与派生4-派生类的构造和析构函数
派生类的构造函数只负责对派生类新增的成员进行初始化,对所有从基类继承下来成员,其初始化工作还是由基类的构造函数完成.同样,对派生类对象的扫尾.清理工作也需要加入新的析构函数. 1.构造函数 构造派生类 ...
- php 派生类 构造,C++派生类的构造函数和析构函数
派生类对象中包含基类对象,因此派生类对象在创建时,除了要调用自身的构造函数进行初始化外,还要调用基类的构造函数初始化其包含的基类对象.因此,程序中任何能够生成派生类对象的语句,都要说明其包含的基类对象 ...
- c++, 派生类的构造函数和析构函数 , [ 以及operator=不能被继承 or Not的探讨]
说明:文章中关于operator=实现的示例,从语法上是对的,但逻辑和习惯上都是错误的. 参见另一篇专门探究operator=的文章:<c++,operator=>http://www.c ...
- C++中基类与派生类的构造函数和析构函数
1.Cpp中的基类与派生类的构造函数 基类的成员函数可以被继承,可以通过派生类的对象访问,但这仅仅指的是普通的成员函数,类的构造函数不能被继承.构造函数不能被继承是有道理的,因为即使继承了,它的名字和 ...
- python3 入门 (四) 类与继承
Python 类 Python中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法. 对象可以包含任意数量和类型的数据. p ...
- C++将类的构造函数、析构函数声明为private或者protected的用途
如果将构造函数.析构函数声明为private或者protected,表示不能从类的外部正常调用构造和析构函数了. 这种用法的通常使用的场景如下: 1.如果不想让外面的用户直接构造一个类A的对象,而希望 ...
- 不要在构造和析构函数中调用虚函数
构造函数中不能有虚函数的原因: 原因一:基类构造期间虚函数不会下降到派生类阶段,也就是本身我们声明一个派生类对象,它应该先去调用基类的构造,若此时基类构造里面有虚函数,则这个虚函数是基类的虚函数,而不 ...
最新文章
- Shell:传递命令行参数
- php mysql 分类_php+mysql实现无限分类实例详解
- php yii 模板引擎,模板引擎(Template Engines)
- navigator.userAgent 取值都带有Mozill的原因。看完我笑了
- 双代号网络图基础算法_9个简单数学算法在管理领域的运用
- [vue] vue常用的修饰符有哪些?列举并说明
- java字符串的方法 1118
- c语言水平制表符怎么才能占16列,水平制表符是?其作用?
- Android UI 备忘:DrawerLayout
- arcgis-tomcat-cors
- SpringBoot第八篇:整合MyBatis-Generator
- 高通msm8953 Android7.1支持Audio设备列表(十二)
- [LeetCode]Letter Combinations of a Phone Number
- winform 报表的基本使用
- mysql索引平衡树hash_MySQL B+树索引和哈希索引的区别
- position:relative的用法
- PgMP项目集管理专家认证培---艾威PgMP培训机构
- SMAA算法详解 - SMAAEdgeDetectionVS
- 在Xcode6中使用故事版来搭建你的工程
- 求解N的N次方的个位数