第八章 C++编程之构造函数与析构函数

第八章 C++编程之构造函数

8.1 什么是构造函数

简单说,构造函数就是在定义某个类的时候会调用的一个函数,默认构造不带参,其余构造函数可以自己实现。

8.2 示例代码—以动物为例

1、定义类的头文件(animal.h)

//以动物为例,实现无参构造和带参构造
#include <iostream>
using namespace std;
class Animal{
private:
	char*name;
	int age;
public:
	Animal(){cout << "this is empty animal" << endl;}//无参构造
	Animal(char *name,int age);//带参构造
	Animal(char *name);//带参构造
	void setName(char *name);
	void setAge(int age);
	void printInfo();
};

2、类的实现函数(animal.cpp)

#include "animal.h"
void Animal::setName(char *name)
{
	this->name = name;
}
void Animal::setAge(int age)
{
	this->age = age;
}
void Animal::printInfo()
{
	cout << "this is " << this->name << ",age = " << this->age << endl;
}
Animal::Animal(char *name,int age)
{
	cout << "Animal(char *name,int age)" << endl;
	this->name = name;
	this->age = age;
}
Animal::Animal(char *name)
{
	cout << "Animal(char *name) " << endl;
	this->name = name;
	this->age = 0;
}

3、主函数(main.cpp)

#include "animal.h"
int main(int argc ,char**argv)
{
	//使用普通的定义方法:若是有多个变量,每个变量重复初始化是麻烦的
	Animal dog[3];//定义的时候会调用默认构造3次
	dog[0].setName("dog:wangcai");
	dog[0].setAge(0);
	dog[0].printInfo();
	dog[0].setName("dog:kangkang");
	dog[0].setAge(1);
	dog[0].printInfo();
	dog[0].setName("dog:xxxx");
	dog[0].setAge(2);
	dog[0].printInfo();
	
	Animal cat("cat",1);//调用带参构造
	cat.printInfo();
	Animal pig("pig");
	pig.printInfo();
	
	Animal*tiger = new Animal("tiger:laohu",2);
	tiger->printInfo();

//	Animal duck();//若是这种情况,相当于:int func(),即这是一个函数声明
	Animal duck;//若想调用无参构造,应该使用这种方式
	return 0;
}

4、Makefile文件

#生成可执行文件person,依赖于文件 main.c和person.c
# 符号的意义: $@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件
main:main.o animal.o
	g++ -o $@ $^
%.o : %.cpp
	g++ -c -o $@ $<
clean:
	rm -rf *.o main

8.3 构造函数的调用过程

构造函数在定义时会被调用,若无实现则调用默认构造,带参时具体调用的哪个构造有类的实际构造函数决定。

8.4 对象指针、指针数组和释放指针空间

8.4.1 分配单个对象指针和释放

1、分配单个指针、使用并释放

#include "animal.h"
int main(int argc ,char**argv)
{
	//1、分配一个对象指针
	Animal *pig  = new Animal();//默认构造
	pig->setName("zhuzhu");
	Animal *dog  = new Animal("dog:wangcai",10);//带参构造
	dog->printInfo();
	delete pig;//此处会调用析构函数
	delete dog;
}

2、在animal.h中增加析构函数,修改后如下

//以动物为例,实现无参构造和带参构造
#include <iostream>
using namespace std;
class Animal{
private:
	char*name;
	int age;
public:
	Animal(){cout << "this is empty animal" << endl;}//构造函数1
	Animal(char *name,int age);//构造函数2
	Animal(char *name);//构造函数3
	Animal(char *name,int age,int num);//构造函数4
	~Animal(){//这是析构函数
		cout << this->name << "out" << endl;
		cout << "this is ~Animal()" << endl;
	}
	void setName(char *name);
	void setAge(int age);
	void printInfo();
};

小结:
1、分配指针对象时(new)调用对应的构造函数
2、删除指针对象时(delete)调用对应的析构函数

8.4.2 分配对象指针数组和释放

1、分配对象指针数组

#include "animal.h"
int main(int argc ,char**argv)
{
	//方式1
	Animal *lion = new Animal[3];
	cout<< "------------------" <<endl;
	lion[0].setName("shizi");
	lion[0].printInfo();
	cout<< "------------------" <<endl;
	//方式2
	Animal *tiger = new Animal[2];
	tiger->setName("laohu_1");//初始化数组对象1
	tiger->printInfo();
	tiger[1].setName("laohu_2");
	tiger[1].printInfo();
	//释放指针数组空间的时候,数组成员有几个就会自动释放几个
	delete []lion;//指针需要主动释放,否则会导致内存泄漏
	delete []tiger;
}

2、在构造函数中申请空间,那么就在析构函数中释放空间
修改animal.h:

//以动物为例,实现无参构造和带参构造
#include <iostream>
using namespace std;
class Animal{
private:
	char*name;
	int age;
public:
	Animal(){
		name = NULL;
		cout << "this is empty animal" << endl;}
	Animal(char *name,int age);
	Animal(char *name);
	Animal(char *name,int age,int num);
	~Animal();
	void setName(char *name);
	void setAge(int age);
	void printInfo();
};

修改animal.cpp:

#include "animal.h"
#include <string.h>
#include <unistd.h>
void Animal::setName(char *name)
{
	if(this->name){
		delete this->name;
	}
	this->name = new char[strlen(name) + 1];
	strcpy(this->name, name);
}
void Animal::setAge(int age)
{
	this->age = age;
}
void Animal::printInfo()
{
	cout << "this is " << this->name << ",age = " << this->age << endl;
}
Animal::Animal(char *name,int age)
{
	cout << "Animal(char *name,int age)" << endl;
	this->name = new char[strlen(name) + 1];
	strcpy(this->name, name);
	this->age = age;
}

Animal::Animal(char *name)
{
	cout << "Animal(char *name) " << endl;
	this->name = new char[strlen(name) + 1];
	strcpy(this->name, name);
	this->age = 0;
}

Animal::Animal(char *name,int age,int num)
{
	cout << "Animal(char *name,int age)" << endl;
	this->name = new char[strlen(name) + 1];
	strcpy(this->name, name);
	this->age = age;
	cout << "number is "<< num << endl;
}

Animal::~Animal()
{
//	cout << "~Animal()" << endl;
	if(this->name){
		delete this->name;
		cout << "-------~Animal()---------"<< this->name << endl;
	}	
}

8.5 小结

析构和构造是C++的重要函数,使用过程比较灵活,需要多积累使用方法。
1、分配指针对象时(new)调用对应的构造函数;
2、删除指针对象时(delete)调用对应的析构函数;
3、函数执行结束后,临时变量被销毁时,会自动调用析构函数,但是指针变量申请了空间不会自动调用析构函数,所以需要手动进行释放。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值