C++对象的初始化和清理

1.构建函数和析构函数

构造函数:

               类名(....){}           可以有参数   无返回值   可以重载  在对象创建时系统自动调用一次

析构函数:

                ~类名() {}                不可以有参数  无返回值  不能重载   对象销毁前系统自动调用一次 

#include <iostream>
using namespace std;

class Person
{
public:

	Person()
	{
		cout << "构造函数" << endl;
	}

	~Person()
	{
		cout << "析构函数" << endl;
	}
};


int main()
{
	Person p;
}

2.构造函数的分类和调用 

 构造函数可以分为普通构造和拷贝构造

 普通构造又可以分为有参构造和无参构造

当然调用也有三种方法

括号法   显示法   隐式转化法 

直接上代码

#include <iostream>
using namespace std;

class Person
{
public:

	Person()
	{
		cout << "无参函数" << endl;
	}
	Person(int)
	{
		cout << "有参构造" << endl;
	}
	Person(const Person & p)
	{
		cout << "拷贝构造" << endl;
	}
	~Person()
	{
		cout << "析构函数" << endl;
	}
};


int main()
{
	//括号法
	Person p1;
	Person p2(10);
	Person p3(p2);
	//显示法
	Person p4 = Person();
	Person p5 = Person(10);
	Person p6 = Person(p5);
	//隐式
	Person p7;
	Person p8 = 10;
	Person p9 = p8;

	Person();//匿名对象,行结束后释放对象
	cout << "hahaha" << endl;
}

注意:1 利用无参构造创建对象不要加()因为系统会看成一个函数声明  Person p1();

 2 不要利用拷贝构造创建匿名对象   因为 Person  (p)----- Person p 会看成创建无参构造对象

 

 

3.拷贝构造函数调用时机 

 这个也比较容易理解  主要是要清楚  值传递的规则

一般拷贝构造函数调用有三种情况

1.使用一个已经创建完的对象创建新的对象

2.值传递的方式给函数参数传值

3.以值方式返回局部对象

值传递是会创建一个新的对象空间   也会在作用域结束后销毁

第一种情况上面已经说明就不写了

上代码


#include <iostream>
using namespace std;
class Person
{
public:
	Person()
	{
		cout << "默认构造" << endl;
	}

	Person(const Person& p)
	{
		cout << "拷贝构造" << endl;
	}
	~Person()
	{
		cout << "析构" << endl;
	}
};

void test(Person p)
{
}
Person text()
{
	Person p;
	return p;
}

int main()
{
	Person p;
	test(p);
	text();//最好接收一下
}

4.构造函数调用规则 

这个很简单,注意用法就行了

1.如果用户定义了有参构造函数,C++就不提供默认构造函数,但提供拷贝构造函数

2.如果用户定义了拷贝构造函数(浅拷贝),就都不提供了

5.深拷贝和浅拷贝

如果用户没有定义拷贝函数,那么C++会提供一个,但是只会浅拷贝

浅拷贝是简单的值拷贝,当属性有在堆区开辟的,必须要用深拷贝,不然会程序会崩掉

代码如下

#include <iostream>
using namespace std;


class Person
{
public:
	Person(int a)//在堆区开辟空间
	{
		height =new int(a);
	}

	Person(const Person& p) //拷贝时默认是浅拷贝,需重新申请一段空间
	{
		height = new int (*p.height);
	}
	~Person()
	{
		if (height != NULL)
		{
			delete(height);
			height = NULL;
		}
		cout << "析构" << endl;
	}
	int* height;
};



int main()
{
	Person p(100);
	Person p1(p);
	cout <<  *p.height << endl;
	cout << *p1.height << endl;
}

图示两种拷贝的区别

6.初始化列表。.....

这个也非常简单  换了一种赋值的方式

Person(int a,int b,int c): m_A=a,m_B=b,m_C=C

{

}

---------------------------------------------------------------------------------

Person(int a,int b,int c)

{

 m_A=a;

 m_B=b;

 m_C=c;

两种赋值方式等价

7.类对象作为类成员 

 当其他类对象作为本类成员,先构造其他类对象,再构造本身

  析构顺序相反

代码

#include <iostream>
using namespace std;

//类对象作类成员
class Lover
{
public:
	Lover(string name) :m_name(name)  //初始化对象列表
	{

	}

	string m_name;
};

class Person
{
public:
	//Lover L  =lover   
	//这个就是隐式转换   创建一个对象  有参构造
	Person(string name, string lover) :n_name(name), L(lover)
	{

	}

	string n_name;
	Lover  L;
};

int main()
{
	Person p("猴","猿");
	cout << p.n_name << endl;
	cout<<p.L.m_name;
}

 8.静态成员

首先成员嘛,所以出现在类中

静态成员变量:

编译阶段就分配空间,类内声明,类外初始化,所有对象共享这份数据

可以通过对象,或者直接通过类名访问这个变量(public 下的)

class Person

{

public :

        static int m;

}

int Person::  m=10;

访问两种方式

1.Person p    

        p.m

2.Person::m

静态成员函数:

所有对象共享一个函数

静态成员函数只能访问静态成员变量(public 下的)

抓住共享就知道,不能访问非静态成员变量

因为非静态成员变量属于特定对象

 

 

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值