C++之赋值函数和析构函数
析构函数
自动调用-------跟 构造函数相近析构函数
特点1:对象消失的时候自动调用
特点2:函数名----类名 相同;前边加~
特点3:系统有默认的析构函数(但它什么都不干)-------当有成员变量是动态内存分配时,就必须重写析构函数
特点4:函数原型永远就1个
//代码:
//main.cpp
#include <iostream>
#include <iomanip>
#include <string.h>
#include <stdlib.h>
#include "Student.h"
using namespace std;
int main()
{
CStudent stu1(1001,"zhangsan");
//stu1.free_name(); //如果没有析构函数,我
们就必须自己定义1个函数,来释放name;并手动来执行。----用了析构只是方便了
return 0;
}
//Student.cpp中完善 析构函数
CStudent::~CStudent()
{
free(name);
cout<<"析构函数运行了"<<endl;
}
如果使用new来建立 对象,就必须使用delete来释放对象------此时析构函数才会被调用
如果使用new来建立 对象,就必须使用delete来释放对象------否则,析构函数不会被调
//用代码:
int main()
{
//CStudent stu1(1001,"zhangsan");
//stu1.free_name();
CStudent *pstu=new CStudent(1001,"zhangsan");
delete pstu;
return 0;
}
赋值函数
特点1:系统有默认的 赋值函数------一般不能用(因为简单的赋值语句,在使用char * name时,会是浅复制)特点2:所以一般要重写
特点3:------不是构造函数(定义变量时调用)
//代码:
//main.cpp
int main()
{
CStudent stu1(1001,"zhangsan");
CStudent stu2(1002,"lisi");
stu2=stu1;//stu2.fun(stu1); //二者几乎等价,所以,我们先来
//定义1个成员函数 fun,实现nummber和name的复制
stu2.print_student();
return 0;
}
赋值函数的书写步骤:
先写fun函数,验证通过后-------将fun替换为operator=----------------main
函数中,直接改为stu2=stu1;
//main.cpp
int main()
{
CStudent stu1(1009,"zhangsan");
CStudent stu2(1002,"lisi");
//stu2=stu1;//stu2.fun(stu1); //二者几乎等价,所以,我们先来
//定义1个成员函数 fun,实现nummber和name的复制
//stu2.operator=(stu1);//fun----- operator=
stu2=stu1;
stu2.print_student();
return 0;
}
//Student.h
void operator=(CStudent &stu1);
//Student.cpp
void CStudent::operator=(CStudent &stu1)
{
number=stu1.number;
//name=stu1.name;
name=(char *)malloc(strlen(stu1.name)+1);
strcpy(name,stu1.name);
return;
}
//进一步完善 赋值函数:
//原因:自己给自己赋值 -----应直接返回;否则,程序会崩溃
//main.cpp
int main()
{
CStudent stu1(1009,"zhangsan");
CStudent stu2(1002,"lisi");
//stu2=stu1;//stu2.fun(stu1); //二者几乎等价,所以,我们先来
定义1个成员函数 fun,实现nummber和name的复制
//stu2.operator=(stu1);//fun----- operator=
//stu2=stu1;
stu2=stu2; //自己给自己赋值----可能会有问
题
stu2.print_student();
return 0;
}
void CStudent::operator=(CStudent &stu1)
{
if(&stu1==this)
{
return;
}
number=stu1.number;
//name=stu1.name;
name=(char *)malloc(strlen(stu1.name)+1);
strcpy(name,stu1.name);
return;
}
//进一步完善 赋值函数:
//原因:链式传送的需求,所以要有返回值
//main.cpp
int main()
{
CStudent stu1(1009,"zhangsan");
CStudent stu2(1002,"lisi");
CStudent stu3(1003,"wangwu");
stu3=stu2=stu1;
stu1.print_student();
stu2.print_student();
stu3.print_student();
return 0;
}
//Student.cpp
CStudent &CStudent::operator=(CStudent &stu1)
{
if(&stu1==this)
{
return *this;
}
number=stu1.number;
//name=stu1.name;
name=(char *)malloc(strlen(stu1.name)+1);
strcpy(name,stu1.name);
return *this;
}
//给name赋值的代码解析:
//代码1:
int main()
{
char *name=new char[10];
name="abcd";
cout<<name;
return 0;
}
//注意:10个内存空间根本没有使用;而且存它的首地址的变量name,被修改后,这10个内
//存空间也永远不会被delete掉,发生了内存泄露
//但输出结果 正常
代码2:
int main()
{
char *name=new char[10];
//name="abcd";
strcpy(name,"abcd");
cout<<name;
return 0;
}
//注意:是深复制。将另外1个字符串"abcd",复制了1份,存到了10个字节的内存空间中(当然只占了前5个字节的空间)
//输出结果 也正常
name ----382c90
----43201c name被改成 该地址
int main()
{
//char name[10]="abcd"; 这行语句等价于下面的语句。 =不是纯粹的赋值
----因为它在定义变量
char name[10];
name[0]="a"; //=是纯粹的赋值,要求2边数据类型要一致--------因为前面
没有 数据类型,说明不是在定义变量
name[1]="b";
return 0;
}
////////////////////////////////////////////////////////////
int main()
{
//char name[10]="abcd";
char *name=new char[10];
strcpy(name,"abcd");
char *name2=name; //这种用法很危险,如下
delete name; //释放name,也相等于 同时释放name2----因为大家指向了同一内存空间
delete name2;
return 0;
}
//进一步完善赋值函数-------name被重新赋值了(使用malloc),而以前name里有"lisi",结果以后再也释放不了了
CStudent &CStudent::fun(CStudent &stu1)
{
if(&stu1==this)
{
return *this;
}
number=stu1.number;
//name=stu1.name;
free(name);
name=(char *)malloc(strlen(stu1.name)+1);
strcpy(name,stu1.name);
return *this;
}
//赋值函数再改进--------考虑到malloc可能会分配失败。
CStudent &CStudent::fun(CStudent &stu1)
{
if(&stu1==this)
{
return *this;
}
number=stu1.number;
//name=stu1.name;
//free(name);
char *name_bak=name;
name_bak=(char *)malloc(strlen(stu1.name)+1);
if(name_bak==NULL)
{
return *this;
}
free(name);
name=name_bak;
strcpy(name,stu1.name);
return *this;
}
1、自定义1个CStudent类,包含学号、姓名、语文成绩、英语成绩。编写4大成员函数。要求使用new/delete cin/cout。在main函数中,建立1个学生数组(可以放3个元素),通过键盘输入学生信息,并打印信息。
2、自定义1个链表类,然后在main函数中,建立1个链表对象,然后通过链表的成员函数,进行3个学生信息,加入到链表中,最后,遍历打印学生信息。
//思路:
#include <iostream>
#include <stdlib.h>
#include <string.h>
//void (*printf_student)(void *data);
class CStudent
{
};
void printf_student(void *data)
{
return;
}
int main()
{
CStudent stu1(1001,"zhangsan");
CLink link;
link.add_node((void *)&stu1);
link.foreach(printf_student);
link.destroy(delete_name);
//link_create();
return 0;
}
知识点:
链表函数库------->封装成CLink类-----》main函数不是 成员函数----只能通过给工程 新建文件 来完成在main函数里,有1条 语句-----建立1个学生,而且还赋值为 1001 "zhangsan"这里出现了 新的 数据类型 CStudnt-----分清它属于 那个模块 ----很具体的1个数据类型,应该属于应用层 顶层
虽然 也属于 顶层,但CStudent如果放置在自己的 .h .cpp 更好所以,该顶层 将有 3个文件在main函数里,有1条 语句-----建立 空链表 CList list;
这里出现了 新的 数据类型 CList-----分清它属于 那个模块 -----很抽象,应该属于 底下1层既然是 地下1层,就要求 该类型的 成员变量、参数------不能有顶层的 数据类型----不能有CStudent,CList list 其实等价于 调用了1个 无参构造函数该函数的功能:应该是 给自己的 成员变量head,赋值,而且为NULL
在main函数里,有1条 语句-----给链表里 增加 节点可以考虑用CList的成员函数来实现
该CList的成员函数,可以直接调用 link.h/link.cpp中的 link_add_node()函
数来实现
考虑到 link_add_node() 是再下1层的
该函数里要 先建立1个 CNode节点
考虑 CNode节点 应为 底下1层
CNode 也通过.h .cpp来写层:由高 到低
main.cpp
Student.h、Student.cpp
List.h/List.cpp
link.h/link.cpp pfun数据类型
Node.h/Node.cpp
如何 添加头文件:
原则:
始终都是 上层 调用 下层
调用时,使用下1层的函数-----使用前要加 下1层的函数原型-------用include .h 省事
实现
//1 类间的关系
//组合 ----- 组装 学生----成绩
//聚合 ----- 聚集 主窗口----- 子窗口
//组合 的使用:
//给学生类 里 放1个 成绩
//成绩-----变量 特殊的变量(类)
//在定义 学生的构造函数时,如何给 chengji变量 赋值?
//利用 CScore的构造函数 来给 chengji 赋值。
//引出了 初始化表------- :chengji(chinese,math,englis) 放置在 函数原型后面(cpp中的,.h不用变)
CStudent::CStudent(int number,char *name,int chinese,int math,int english):chengji(chinese,math,english)//初始化表
{
this->number=number;
this->name=new char[strlen(name)+1];
strcpy(this->name,name);
//this->chinese=chinese;
//this->math=math;
//this->english=english;
//chengji.CScore(chinese,math,english); 因为CScore()是构造函数,不能这么用
}
//小技巧:
//调用CStudent的print函数时,可以调用 CScore的print函数
//组合代码:
//main.cpp
#include "Student.h"
int main()
{
CStudent stu1(1001,"zhangsan",61,62,63);
stu1.print_student();
return 0;
}
//Student.h
// Student.h: interface for the CStudent class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_STUDENT_H__6C8339B9_6432_4E34_A210_A960F4A095CC__INCLUDED_)
#define AFX_STUDENT_H__6C8339B9_6432_4E34_A210_A960F4A095CC__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "Score.h"
class CStudent
{
public:
int number;
char *name;
//int chinese;
//int math;
//int english;
CScore chengji;
CStudent();
virtual ~CStudent();
CStudent(int number,char *name,int chinese,int math,int english);
void print_student();
};
#endif // !defined(AFX_STUDENT_H__6C8339B9_6432_4E34_A210_A960F4A095CC__INCLUDED_)
//Student.cpp
// Student.cpp: implementation of the CStudent class.
//
//////////////////////////////////////////////////////////////////////
#include <iostream>
#include "Student.h"
using namespace std;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CStudent::CStudent()
{
}
CStudent::~CStudent()
{
}
CStudent::CStudent(int number,char *name,int chinese,int math,int english):chengji(chinese,math,english)//初始化表
{
this->number=number;
this->name=new char[strlen(name)+1];
strcpy(this->name,name);
//this->chinese=chinese;
//this->math=math;
//this->english=english;
//chengji.CScore(chinese,math,english); 因为CScore()是构造函数,不能这么用
}
void CStudent::print_student()
{
cout<<"number is "<<number<<endl<<"name is "<<name<<endl;
//cout<<"chines is "<<chengji.chinese
chengji.print_chengji();
return;
}
//Score.h
class CScore
{
public:
int chinese;
int math;
int english;
CScore();
CScore(int chinese,int math,int english);
virtual ~CScore();
void print_chengji();
};
//Score.cpp
// Score.cpp: implementation of the CScore class.
//
//////////////////////////////////////////////////////////////////////
#include <iostream>
#include "Score.h"
using namespace std;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CScore::CScore()
{
}
CScore::~CScore()
{
}
CScore::CScore(int chinese,int math,int english)
{
this->chinese=chinese;
this->math=math;
this->english=english;
}
void CScore::print_chengji()
{
cout<<"chinese is "<<chinese<<" math is "<<math<<" english is "<<english<<endl;
return;
}
声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。
- 上一篇:没有了
- 下一篇:没有了
