接着上一节,今天讲C++中类的构造函数与析构函数,对象的赋值与复制.

  1.用过C#语言的人,都知道构造函数是一种特殊的成员函数,它主要用于对对象分配空间,进行初始化。构造函数的名字必须与类名相同。可以有任何类型的参数,但不返回任何值,是在建立对象时自动执行的。和上一节一样,还是用Kid类来说明。

 1 class Kid 2 { 3 private: 4 int age; 5 char*name; 6 char*sex; 7 public: 8         Kid(int age,char*name,char*sex); 9 void showKid();10 };11 12 Kid::Kid(int age,char*name,char*sex)13 {14     Kid::age=age;15     Kid::name=name;16     Kid::sex=sex;17 }18 19 void Kid::showKid()20 {21     cout<<"姓名:"<<name<<endl<<"年龄:"<<age<<endl<<"性别:"<<sex<<endl;22 }

  接下来,建立对象并初始化:Kid kid(10,"rookie_j","男");另外一种使用new运算符动态建立对象:Kid *ptr=new Kid(10,"rookie_j","男");通过指针变量ptr来访问:ptr->showKid();当我们用new建立对象时,当不再使用它时,要用delete运算符释放它:delete ptr;和不同成员函数一样,如果构造函数定义在类体内部,则作为内联函数处理;

  在声明类时,对数据成员的初始化一般在构造函数中用赋值语句进行,但C++还提供了另外一种初始化数据成员的方法——用成员初始化表来实现对数据成员的初始化。它的一般形式为:类名::构造函数名([参数表]):[(成员初始化表)];成员初始化表的形式为:成员名1(初始值1),成员名2(初始值2),成员名2(初始值2);比如:

Kid::Kid(int age,char *name,char *sex):age(age),name(name),sex(sex){};

  接下来讲一下析构函数:在我第一次在C++里看到这个名词时,感觉这个知识点很深奥,结果看了以后,其实很简单。它的作用和构造函数刚好相反,用于撤销对象,如:释放分配给对象的内存空间。析构函数和构造函数名相同,但在其前面要加~符号,析构函数没有参数,也没有返回值,且不能重载,因此一个类中只有一个析构函数。以下三种情况,当对象的生命周期结束时,析构函数会被自动调用:(1)定义了全局对象,则在程序流程离开其作用域(如:main函数结束或调用Exit)时,调用该全局对象的析构函数;(2)对象被定义在函数体里,则当这个函数执行完后,该对象释放,析构函数被自动调用;(3)若一个对象使用new运算符动态创建的,在使用delete运算符释放它时,会自动调用析构函数;

View Code

 1 #include "stdafx.h" 2 #include <iostream> 3  4 usingnamespace std; 5  6 class Kid 7 { 8 private: 9 int age;10 char*name;11 char*sex;12 public:13         Kid(int age,char*name,char*sex);14 ~Kid();15 void showKid();16 };17 18 19 Kid::Kid(int age,char*name,char*sex)20 {21     Kid::age=age;22     Kid::name=newchar[strlen(name)];23     strcpy(Kid::name,name);24     Kid::sex=newchar[strlen(sex)];25     strcpy(Kid::sex,sex);26 }27 28 Kid::~Kid()29 {30     cout<<"dispose object kid"<<endl;31     delete []name;32     delete []sex;33 }34 35 void Kid::showKid()36 {37     cout<<"姓名:"<<name<<endl<<"年龄:"<<age<<endl<<"性别:"<<sex<<endl;38 }39 40 41 int main()42 {43     Kid kid(10,"rookie_j","男");44     kid.showKid();45 46     Kid *ptr=new Kid(10,"rookie_x","女");47     ptr->showKid();48 49     delete ptr;50 51 return0;52 }

结果:

  如果没有给类定义构造函数,则编译系统自动地生成一个默认的构造函数,比如在Kid类中编译系统会为其产生一个Kid::Kid(){};构造函数,这个默认的构造函数只能给对象开辟存储空间,不能给数据成员赋值,这时数据成员的初值就是随机数。对没有定义构造函数的类,其公有数据成员可以用初始化值表进行初始化,如:

 1 class Kid 2 { 3 public: 4 int age; 5 char*name; 6 char*sex; 7 }; 8  9 int main()10 {11 12     Kid kid={10,"Rookie_j","男"};13     cout<<"姓名:"<<kid.name<<endl<<"年龄:"<<kid.age<<endl<<"性别:"<<kid.sex<<endl;14 15 return0;16 }

但只要一个类定义了构造函数,系统将不再给它提供默认构造函数;另外还有默认的析构函数(Kid::~Kid(){}),一般来说默认的析构函数就能满足要求,但对一些需要做一些内部处理的则应该显式定义析构函数。带默认参数的构造函数和之前所说的带参数的成员函数是一样的,对于构造函数的重载,在这里我就不多说了,只想强调一点,如果是无参的构造函数创建对象,应该使用"类名 对象名"的形式,而不是"类名 对象名()";

  2.对象的赋值其实和变量的赋值差不多,也是用赋值运算符=进行的,只不过进行赋值的两个对象的类型必须相同,对象之间的赋值只是数据成员的赋值,而不对成员函数赋值;

View Code

 1 #include "stdafx.h" 2 #include <iostream> 3  4 usingnamespace std; 5  6 class Kid 7 { 8 private: 9 int age;10 char*name;11 char*sex;12 public:13         Kid(int age,char*name,char*sex);14         Kid(){    };15 ~Kid();16 void showKid();17 };18 19 20 Kid::Kid(int age,char*name,char*sex)21 {22     Kid::age=age;23     Kid::name=newchar[strlen(name)];24     strcpy(Kid::name,name);25     Kid::sex=newchar[strlen(sex)];26     strcpy(Kid::sex,sex);27 }28 29 Kid::~Kid()30 {31     cout<<"dispose object kid"<<endl;32     delete []name;33     delete []sex;34 }35 36 void Kid::showKid()37 {38     cout<<"姓名:"<<name<<endl<<"年龄:"<<age<<endl<<"性别:"<<sex<<endl;39 }40 41 int main()42 {43     Kid kid(10,"rookie_j","男"),kid2;44     kid.showKid();45 46     kid2=kid;47     kid2.showKid();48 49 return0;50 }

结果:

  拷贝构造函数是一种特殊的构造函数,其形参是类对象的引用。它主要用于在建立一个新的对象时,使用已经存在的对象去初始化这个新对象。拷贝构造函数也是构造函数,所以函数名必须与类名相同,参数只有一个就是同类对象的引用,每个类必须要有一个拷贝构造函数。如果程序员自己不定义拷贝构造函数,系统会自动产生一个默认拷贝构造函数。调用拷贝构造函数的形式有代入法:类名 对象2(对象1)和赋值法:类名 对象2=对象1;

View Code

 1 #include "stdafx.h" 2 #include <iostream> 3  4 usingnamespace std; 5  6 class Kid 7 { 8 private: 9 int age;10 char*name;11 char*sex;12 public:13         Kid(int age,char*name,char*sex);14         Kid(const Kid &kid);15 ~Kid();16 void showKid();17 };18 19 20 Kid::Kid(int age,char*name,char*sex)21 {22     Kid::age=age;23     Kid::name=newchar[strlen(name)];24     strcpy(Kid::name,name);25     Kid::sex=newchar[strlen(sex)];26     strcpy(Kid::sex,sex);27 }28 29 Kid::Kid(const Kid &kid)30 {31     Kid::age=kid.age*2;32     Kid::name=newchar[strlen(kid.name)];33     strcpy(Kid::name,kid.name);34     Kid::sex=newchar[strlen(kid.sex)];35     strcpy(Kid::sex,kid.sex);36 }37 38 Kid::~Kid()39 {40     cout<<"dispose object kid"<<endl;41     delete []name;42     delete []sex;43 }44 45 void Kid::showKid()46 {47     cout<<"姓名:"<<name<<endl<<"年龄:"<<age<<endl<<"性别:"<<sex<<endl;48 }49 50 int main()51 {52     Kid kid(10,"rookie_j","男");53     kid.showKid();54 55     Kid kid2(kid);56     kid2.showKid();57 58     Kid kid3=kid2;59     kid3.showKid();60 61 return0;62 }

结果:

  同样的默认的拷贝构造函数:复制出与源对象的数据成员的值一样的新对象。调用拷贝构造函数的3种情况:(1)Kid kid2(kid1)或Kid kid2=kid1;(2)函数的形参是类的对象:fun(Kid kid){kid.showKid();}; int main(){Kid kid(10,"Rookie_j","男");fun(kid);return 0;};(3)函数返回值为类的对象:Kid fun(){Kid kid(10,"Rookie_j","男"); return kid;} int main(){ Kid kid; kid=fun();kid.showKid();return 0;};

  3.最后还是一样用一个实例来总结一下今天所说的内容(开发工具:vs2010):

View Code

  1 #include "stdafx.h"  2 #include <iostream>  3   4 usingnamespace std;  5   6 class Kid  7 {  8 private:  9 int age; 10 char*name; 11 char*sex; 12 public: 13         Kid(int age,char*name,char*sex); 14         Kid(const Kid &kid);  //自定义拷贝函数 15 ~Kid();  16 void showKid(); 17 }; 18  19  20 Kid::Kid(int age,char*name,char*sex) 21 { 22     Kid::age=age; 23     Kid::name=newchar[strlen(name)]; 24     strcpy(Kid::name,name); 25     Kid::sex=newchar[strlen(sex)]; 26     strcpy(Kid::sex,sex); 27 } 28  29 //Kid::Kid(int age,char *name,char *sex):age(age),name(name),sex(sex) //用成员初始化表对数据成员初始化 30 //{ 31 // 32 //} 33  34 Kid::Kid(const Kid &kid) 35 { 36     Kid::age=kid.age*2; 37     Kid::name=newchar[strlen(kid.name)]; 38     strcpy(Kid::name,kid.name); 39     Kid::sex=newchar[strlen(kid.sex)]; 40     strcpy(Kid::sex,kid.sex); 41 } 42  43 Kid::~Kid() //自定义析构函数 44 { 45     cout<<"dispose object kid"<<endl; 46     delete []name; //delete运算符释放存储空间 47     delete []sex; 48 } 49  50 void Kid::showKid() 51 { 52     cout<<"孩子:"<<endl<<"姓名:"<<name<<endl<<"年龄:"<<age<<endl<<"性别:"<<sex<<endl; 53 } 54  55 class Car 56 {     57 public: 58 char*no; 59 char*brand; 60 int speed; 61 void showCar(); 62 ~Car(){};//仿默认析构 63 }; 64  65  66  67 void Car::showCar() 68 { 69     cout<<"汽车:"<<endl<<"号码:"<<no<<endl<<"品牌:"<<brand<<endl<<"速度:"<<speed<<"km/h"<<endl; 70 } 71  72 int main() 73 { 74     Kid kid(10,"rookie_j","男"); 75     kid.showKid(); 76  77     cout<<"--------------------"<<endl; 78  79     Kid kid2(kid); //代入法调用拷贝构造函数 80     kid2.showKid(); 81  82     cout<<"--------------------"<<endl; 83  84     Kid kid3=kid2; //赋值法调用拷贝构造函数 85     kid3.showKid(); 86  87     cout<<"--------------------"<<endl; 88  89     Kid *ptr=new Kid(10,"rookie_x","女"); //使用new运算符动态创建对象 90     ptr->showKid(); 91  92     cout<<"--------------------"<<endl; 93  94 //delete ptr; //释放对象所占的存储空间 95  96     Car car={"8888888","Benz",200},car2;//只有没定义构造函数的类,才能用初始值表初始化公有数据成员,默认构造 97     car.showCar(); 98      99 100     cout<<"--------------------"<<endl;101 102     car2=car;//默认拷贝构造函数或car2(car)103     car2.showCar();104 105     cout<<"--------------------"<<endl;106 107 return0;108 }

结果:

但在运行的时候,发现一个问题如果把delete ptr; 这句的注释去掉,结果汽车的情况就显示不出来了;

结果:

不知道为什么?求助各位大侠!

转载于:https://www.cnblogs.com/CaiNiaoZJ/archive/2011/07/24/2115041.html

C++之类与对象(2)相关推荐

  1. java_B站_面试题

    Java面向对象有哪些特征,如何应用 ​ 面向对象编程是利用类和对象编程的一种思想.万物可归类,类是对于世界事物的高度抽象 ,不同的事物之间有不同的关系 ,一个类自身与外界的封装关系,一个父类和子类的 ...

  2. 史上最详细的23中设计模式解析,一个不落,理论搭配简单案例,更好理解哦

    目录 一.软件设计模式的产生背景 二.软件设计模式的概念与意义 1. 软件设计模式的概念 2. 学习设计模式的意义 三.23 种设计模式的分类和功能 1. 根据目的来分 2. 根据作用范围来分 3. ...

  3. 在kotlin companion object中读取Bean,注入Bean对象

    在kotlin companion object中读取Bean,注入Bean对象 在使用kotlin时,或多或少地会使用到一些公共组件,如 http. mongo. redis相关的组件.   使用组 ...

  4. IDEA自动生成对象所有set方法

    idea中有一款插件能够生成对象所有的set方法,GenerateAllSetter :下载地址 步骤1:将下载好的压缩包放在自己记得的文件夹中,在idea中进行导入 步骤2:在本地选中刚才的压缩包, ...

  5. 基于Golang的对象序列化的程序包开发——myJsonMarshal

    基于Golang的对象序列化的程序包开发--myJsonMarshal[阅读时间:约10分钟] 一.对象序列化概述 二.系统环境&项目介绍 1.系统环境 2.项目的任务要求 三.具体程序设计及 ...

  6. java 捕获异常并存入数据库_java异常处理,报异常的话怎么处理对象值,并持久化到数据库中...

    展开全部 //没看到有人回e68a843231313335323631343130323136353331333365646233答你,我还没学到框架,不知道那个是不是可以很便捷操作你说的这样过程 / ...

  7. python程序如何执行死刑图片_如何判断对象已死

    已死的对象就是不可能被任何途径使用的对象,有以下几种方法判断一个对象是否已经死了: 引用计数 给对象添加一个引用计数器,每当有一个地方引用他,计算器就加 1:当引用失效时,计数器减 1:任何时刻计数器 ...

  8. Go 学习笔记(64)— Go error.New 创建接口错误对象、fmt.Errorf 创建接口错误对象、errors.Is 和 errors.As

    1. error 接口定义 除用 panic 引发中断性错误外,还可返回 error 类型错误对象来表示函数调用状态.error 接口是 Go 原生内置的类型,它的定义如下: // $GOROOT/s ...

  9. OpenCV 笔记(06)— Mat 结构、像素值存储方法、创建 Mat 对象各种方法、Mat 对象的运算

    数字图像中的每个点都称为像素(对于图像元素),并且每个像素可以存储一个或多个值,这取决于它是否是仅存储一个值的黑白图像(也称为二进制图像,比如只存储0或1),还是存储两个值的灰度图像,或者是存储三个值 ...

  10. NumPy — 创建全零、全1、空、arange 数组,array 对象类型,astype 转换数据类型,数组和标量以及数组之间的运算,NumPy 数组共享内存

    NumPy 简介 一个用 python 实现的科学计算包.包括: 1.一个强大的 N 维数组对象 Array : 2.比较成熟的(广播)函数库: 3.用于整合 C/C++ 和 Fortran 代码的工 ...

最新文章

  1. 嵌入式目标检测--Fast YOLO: A Fast You Only Look Once System for Real-time Embedded Object Detection
  2. Excel中条件格式应用的探讨之突出显示!
  3. crontab+php-cgi/php 定时执行PHP脚本
  4. origin master 出现The authenticity of host 'github.com ' can't be established
  5. Azure Services Platform
  6. 如何删除textarea的移动版Safari的阴影?
  7. enityframework 已连接的当前状态为打开。_关于性能优化 从tcp建立连接amp;断开的视角...
  8. c#使用zlib.net压缩解压byte数组
  9. js生成带log的二维码(qrcodejs)
  10. MySQL可视化工具之Navicat for MySQL
  11. C# JPG转PDF
  12. makefile终极目标
  13. 质量管理三个概念:QC、QA和QM 解析
  14. 怎么在python官网下载python,python的官方网址是什么
  15. 因子分析(factor analyis)
  16. DPDK环境搭建报错及解决方法总结
  17. 太乐地图下载器 V5.0.5 破解版
  18. 计算机网络课后答案(朱晓姝版)
  19. UVA 1645 Count——dp
  20. 公共域名服务DNS 114.114.114.114和8.8.8.8

热门文章

  1. (二叉树DFS)天平UVa 839
  2. js java post提交_如何从Express.js发送Post请求到另一个服务器(Java)?
  3. mtk android 5.1 logo,Android ROM DIY之MTK平台手机通用移植
  4. HTML+CSS+JS实现 ❤️绘制卡丁车动漫特效❤️
  5. 基于java(springboot+mybatis)汽车信息管理系统设计和实现以及文档
  6. arrays合并两个数组_每天一道力扣题: 88. 合并两个有序数组
  7. 二元函数洛必达求极限_洛必达法则的几个例子
  8. Java中12个原子操作类
  9. python tkinter数据库通讯录_TKINTER--GUI连接数据库登陆
  10. android studio viewo,Android Studio 之 ViewModel