c++中的构造函数和析构函数
Posted Heisenberg_Posion
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++中的构造函数和析构函数相关的知识,希望对你有一定的参考价值。
构造函数和析构函数的产生
对象的初始化和清理,就像电子产品的出厂设置一样。
构造函数就是进行对象的初始化,析构函数是对象的清理。
需要知道的是构造函数和析构函数会自己自动运行,只要你创建了一个对象就会调用构造函数。
作用
构造函数主要作用在于为对象的成员赋值属性赋值。
析构函数作用在于对象销毁前执行一些清理工作。
函数语法
构造函数
类名()
1.没有返回值,也不写void
2.函数名称与类名相同
3.可以有参数,可以发生重载
4.自动调用,并且只会调用一次
析构函数
~类名 ()
1.没有返回值,也不写void
2.函数名称与类名相同,函数名前加~
3.不可以有参数
4.自动调用,且只会调用一次
#include<iostream>
using namespace std;
class Person
public:
Person() //构造函数
cout << "this is the beginning" << endl;
~Person() //析构函数
cout << "this is the end\\n" << endl;
;
int main()
Person zhujialing; //无函数调用,因为它会自己调用,看程序输出结果就知道了
return 0;
构造函数的分类和调用
1.按照参数类型分为 无参构造和有参构造,构造函数可以是有参数的,因此可以这样分类
2.按照类型分类, 普通构造和拷贝构造,知道什么是拷贝构造,然后其他的都叫做普通构造
拷贝构造就是复制一个已经创建好的对象的属性来对你要新创建的对象赋予初值
Person(const Person &p) //拷贝构造函数复制人的信息是用const,这可以用来确保被复制的人的信息不变,加&是为了节约空间,这样可以直接拿到那份复制人的信息;
cout << "拷贝构造函数" << endl;
age = p.age;
name = p.name;
调用方法分为三种:括号法,显示法,隐式转换法,只要知道括号法就够了,后面两种的用法基本见不到,但是还是可以了解一下。
#include<iostream>
using namespace std;
class Person
public:
Person()
cout << "无参构造函数" << endl;
Person(int a)
age = a;
cout << "有参构造函数" << endl;
Person(const Person &p) //拷贝构造函数复制人的信息是只能用const来确保被复制的人的信息不变并为了节约空间,加&;
cout << "拷贝构造函数" << endl;
age = p.age;
name = p.name;
~Person()
cout << "析构函数" << endl;
public:
int age;
string name;
;
//括号法
Person p1;
Person p2(10);
Person p3(p2);
//显示法
Person p1;
Person p2 = Person(10); //Person(10)叫做匿名化创建一个对象,在代码行执行完一行后就会被析构掉,这个在后面的容器学习里面会用到。
Person p3 = Person(p2); //不要利用Person(p2)去初始化匿名对象,因为Person(p2)==Person p2,会造成重定义
//隐式转换法
Person p2 = 10; //Person p2 =Person(10) 有参构造
Person p3 = p2; //拷贝构造
拷贝构造函数的调用时机
1.初始化对象,复制信息;
Person p1(p2) //复制p2的信息创建一个新的对象p2
2.值传递的方式给函数参数传值,意思是一个对象作为函数参数时,会创建一个一样的对象来给函数作为参数
void Dowork(Person p)
void test0()
Person p1;
Dowork(p1); //这里会用到拷贝构造函数,创建一个和p1一样的对象
3.值方式返回局部对象,返回的对象是拷贝出来的对象
Person Dowork()
Person p1;
return p1; //这个函数返回的对象是拷贝出来的。
深拷贝与浅拷贝
浅拷贝只是简单的进行了=操作,深拷贝是在堆区重新开辟了一个空间来存放数据。
浅拷贝时,如果拷贝的是程序员自己开辟的指针的话,当要去释放时,会释放已经释放掉的指针,这是非法的操作,从而程序会报错
具体看代码。
#include<iostream>
using namespace std;
class Person
public:
Person()
cout << "无参构造函数" << endl;
Person(int age,int height)
cout << "有参构造函数" << endl;
m_age = age;
m_height = new int(height); //程序员new的要手动delete掉,这个是在析构函数里面实现。
Person(const Person &p)
cout << "拷贝构造函数" << endl;
m_age = p.m_age;
m_height = new int(*p.m_height); //指向一块新的内存空间,如果不这样,直接将p.m_height赋值给m_heightd的话,这个新创建对象的m_height和复制的p的m_height指向的是同一个地址,但是两个对象都要释放指针,就会出现释放一个已经释放了的指针,这是非法的。
~Person()
if (m_height != NULL)
delete m_height;
m_height = NULL;
cout << "析构函数" << endl;
public:
int m_age;
int *m_height;
;
int main()
Person p1(18, 180);
Person p2(p1);
cout << p1.m_age<<" "<<*p1.m_height << endl;
cout << p2.m_age << " " << *p2.m_height << endl; //浅拷贝拷贝的是指针地址,当第一个析构函数进行时,指针已经被释放了,当第二个析构函数进行时,再去释放一个已经被释放的指针是非法的,因此这时候就需要用到深拷贝,自己去重新建立一个堆区空间存放指针指向的数据;
return 0;
以上是关于c++中的构造函数和析构函数的主要内容,如果未能解决你的问题,请参考以下文章