C++学习笔记——构造函数与析构函数

在visual studio中可直接运行

#include <iostream>
#include <string>

using namespace std;

/******************************************************************
 1、构造函数和析构函数
     (1)构造函数   格式:类名() {}
	      a.没有返回值,也不写void
		  b.函数名与类名相同
		  c.可以有参数,可以发生重载
		  d.程序在调用对象的时候会自动调用构造函数,无需手动调用,而且只会调用一次
     (2)析构函数   格式:~类名() {}
		  a.没有返回值,也不写void
		  b.函数名与类名相同,在名称前加~
		  c.不可以有参数,不可以发生重载
		  d.程序在对象销毁前自动调用析构,无需手动调用,而且只会调用一次
 ******************************************************************/

 /******************************************************************
 2、构造函数的分类和调用
   (1)两种分类方式
		 a.按参数分类:有参构造函数(默认构造)和无参构造函数
		 b.按类型分类:普通构造函数和拷贝构造函数
   (2)三种调用方式
		 a.括号法
		 b.显示法
		 c.隐式转换法
 ******************************************************************/

 /******************************************************************
 3、拷贝构造函数调用时机
 (1)使用一个已经创建完毕的对象来初始化一个新对象
 (2)值传递的方式给函数参数传值
 (3)以值方式返回局部对象
 ******************************************************************/

 /******************************************************************
 4、构造函数的调用规则
 默认情况下,C++编译器至少给一个类添加3个函数
 (1)默认构造函数(无参,函数体为空)
 (2)默认析构函数(无参,函数体为空)
 (3)默认拷贝构造函数,对属性进行值拷贝

 构造函数的调用规则:
 (1)如果用户定义有参构造函数,C++不再提供默认无参构造,但是会提供默认拷贝构造
 (2)如果用户定义拷贝构造函数,C++不再提供其他构造函数
 ******************************************************************/

 /******************************************************************
 5、深拷贝与浅拷贝
	深拷贝:在堆区重新申请空间,进行拷贝操作
	浅拷贝:简单地赋值拷贝操作
 ******************************************************************/

 /******************************************************************
 6、初始化列表  用于初始化属性
 语法:构造函数():属性1(值1),属性2(值2)...{}
 ******************************************************************/

 /******************************************************************
 7、类对象作类成员
    class A{}
	class B{A a;}
	当类中成员是其他类对象时,我们称该成员为 对象成员
	构造顺序:先调用对象成员的构造,在调用本类构造
	析构顺序与构造相反
 ******************************************************************/

 /******************************************************************
 8、静态成员
    静态成员就是在成员变量和成员函数前加上关键字static,称为静态成员
    静态成员分为:
    (1)静态成员变量
		a.所有对象共享同一份数据
		b.在编译阶段分配内存
		c.类内声明,类外初始化
	(2)静态成员函数
		a.所有对象共享同一个函数
		b.静态成员函数只能访问静态成员变量
 ******************************************************************/
class Car
{
public:
	Car() {}
	Car(int a, int b, int c) :m_A(a), m_B(b), m_C(c) 
	{
		cout << "调用Car的无参构造函数" << endl;
	}
	~Car()
	{
		cout << "调用Car的析构函数" << endl;
	}
	void printCar()
	{
		cout << "m_A=" << m_A << endl;
		cout << "m_B=" << m_B << endl;
		cout << "m_C=" << m_C << endl;
	}

	int m_A;
	int m_B;
	int m_C;
private:

};
class Person
{
public:
	//构造函数
	Person()
	{
		cout << "调用Person的无参构造函数" << endl;
	}
	Person(int a)
	{
		age = a;
		cout << "调用Person的有参构造函数" << endl;
	}
	Person(int a,int height)
	{
		age = a;
		m_Height = new int(height);//开辟在堆区,对象销毁前释放
		cout << "调用Person的两个入口参数的有参构造函数" << endl;
	}
	//自己实现拷贝构造函数,解决浅拷贝带来的问题
	Person(const Person &p)//const修饰,不能修改,
	{
		age = p.age;//将传入的人身上的所有属性,拷贝到我身上
		//m_Height = height;编译器默认拷贝函数实现的就是这行代码
		//深拷贝操作
		m_Height = new int(*p.m_Height);
		cout << "调用Person的拷贝构造函数" << endl;
	}
	~Person()
	{
		//析构代码,将堆区开辟数据做释放操作
		if (m_Height != NULL)
		{
			delete m_Height;
			m_Height = NULL;
		}
		cout << "调用Person的析构函数" << endl;
	}
	//静态成员函数
	static void func()
	{
		m_A = 100;//静态成员函数可以访问静态变量,该数据共享,只有一份
		//m_B = 200;//静态成员函数不可以访问非静态成员变量,无法区分到底是哪个对象的m_B
		cout << "调用static void func()" << endl;
	}
	int age;
	int * m_Height;
	static int m_A;
	int m_B;
	Car m_Pcar;//类对象成员
private:
	//静态成员函数也会有访问权限,类外不能访问
	static void func2()
	{
		cout << "调用static void func2()" << endl;
	}
};
int Person::m_A = 0;//静态成员变量类外初始化

/******************************************************************
2、构造函数的分类和调用
******************************************************************/
//构造和析构都是必须实现的,如果我们自己不提供,编译器会提供一个空实现的构造和析构
//调用
void test01()
{
	//1、括号法
	Person p1;//局部变量,存放在栈区,函数运行完释放(默认构造函数调用)
	Person p2(10);//有参构造函数调用
	Person p3(p2);//拷贝构造函数调用
	//注意事项1
	//调用默认构造函数,不加()
	//下面这行代码,编译器会认为是一个函数的声明,不会认为在创建对象
	//Person p1();
	cout << "p2的年龄:" << p2.age << endl;
	cout << "p3的年龄:" << p3.age << endl;

	//2、显示法
	Person p4 = Person(10);//有参构造
	Person p5 = Person(p4);//拷贝构造

	//Person(10);//匿名对象  特点:当前执行结束后,系统会立即收回匿名对象
	//cout << "1111" << endl;

	//注意事项2
	//不要利用拷贝构造函数初始化匿名对象,编译器会认为Person(p5) === Person p5;对象声明
	//Person(p5);

	//3、隐式转换法
	Person p6 = 10;//相当于写了 Person p4 = Person(10);有参构造
	Person p7 = p6;//拷贝构造
}
/******************************************************************
3、拷贝构造函数调用时机
******************************************************************/
//(1)使用一个已经创建完毕的对象来初始化一个新对象
void test02()
{
	Person p1(20);
	Person p2(p1);
	cout << "p2的年龄:" <<p2.age<< endl;
}
//(2)值传递的方式给函数参数传值
void doWork(Person p)
{

}
void test03()
{
	Person p;
	doWork(p);
}
//(3)以值方式返回局部对象
Person doWork2(void)
{
	Person p1;
	cout << (int *)&p1 << endl;
	return p1;
}
void test04()
{
	Person p = doWork2();
	cout << (int *)&p << endl;
	
}
/******************************************************************
5、深拷贝与浅拷贝
深拷贝:在堆区重新申请空间,进行拷贝操作
浅拷贝:简单地赋值拷贝操作
******************************************************************/
void test05()
{
	Person p1(18,160);
	cout << "p1的年龄:" << p1.age << " p1的身高:" << *p1.m_Height << endl;
	//利用编译器提供的拷贝构造函数,会做浅拷贝,  
	//浅拷贝带来的问题是堆区的内存重复释放
	//利用深拷贝进行解决
	Person p2(p1);
	cout << "p2的年龄:" << p2.age << " p2的身高:" << *p2.m_Height << endl;
}
/******************************************************************
8、静态成员
静态成员就是在成员变量和成员函数前加上关键字static,称为静态成员
******************************************************************/
//有两种访问方式
void test06()
{
	//通过对象访问
	Person p;
	p.func();
	//通过类名访问
	Person::func();
}
int main()
{
	//test01();//调用构造函数方法
	//test02();//使用一个已经创建完毕的对象来初始化一个新对象
	//test03();//值传递的方式给函数参数传值
	//test04();//以值方式返回局部对象
	//test05();//深拷贝与浅拷贝
	//Car car(1,2,3);//列表初始化
	//car.printCar();
	//test06();//静态成员
	system("pause");
	return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: C++面向对象编程中,构造函数析构函数是两个非常重要的概念。 构造函数是一种特殊的函数,它在对象创建时自动调用,用于始化对象数据成员。构造函数的名称与类名相同,没有返回值类型,可以有参数,可以有多个构造函数,以便在创建对象时进行不同的始化操作。 析构函数是一种特殊的函数,它在对象被销毁时自动调用,用于清理对象的资源。析构函数的名称与类名相同,前面加上一个波浪号(~),没有返回值类型,不接受任何参数。 构造函数析构函数C++面向对象编程中的两个重要概念,它们的作用是始化对象和清理对象的资源,是面向对象编程的基础。 ### 回答2: 面向对象是一种程序设计的方法,它以对象为中心,通过封装、继承和多态等机制来组织和管理代码,使程序更加可靠、可重用和易于维护。其中,构造函数析构函数是面向对象程序设计中的重要概念。 构造函数是一种特殊的成员函数,它在对象创建时自动被调用,用于对对象进行始化。构造函数的名称与类名相同,没有返回值,可以重载,可以带参数,也可以不带参数。构造函数的作用是保证对象创建时始终处于一种可靠的状态,从而避免程序运行时的错误和异常。 析构函数是与构造函数相对应的一种成员函数,它在对象销毁时自动被调用,用于对对象进行善后处理。析构函数的名称与类名相同,前面加上一个波浪号(~),没有参数,也没有返回值。析构函数的作用是释放对象所占用的资源,例如动态分配的内存、打开的文件、建立的连接等,在对象销毁之前要确保这些资源已经被回收,从而避免内存泄漏和资源浪费。 构造函数析构函数是面向对象程序设计中的重要组成部分,它们体现了对象的生命周期和和管理方式,尤其是在涉及到动态内存分配和释放时更为重要。正确使用构造函数析构函数可以提高程序的可靠性、可重用性和可维护性,从而更好地实现程序模块化和复用。因此,在面向对象程序设计中,构造函数析构函数应该被视为重要的设计关注点,特别是在涉及到大型程序或长期运行的系统时。 ### 回答3: 面向对象编程是一种广泛使用的编程范式,它关注的是对象的行为和属性,而不是函数和逻辑。构造函数析构函数是面向对象编程中的两个重要概念,在类的实例化和释放过程中起到了关键的作用。 构造函数是一个类的特殊函数,它习惯性地与类名相同,用于始化类的实例。构造函数可以接收参数,这些参数可以用来始化类的成员变量。每当一个对象创建时,构造函数会自动调用,以确保对象被正确地始化。如果类没有定义构造函数,编译器将提供一个默认构造函数析构函数是一个类的另一个重要函数,它也习惯性地与类名相同,用于释放由该类创建的资源。析构函数通常用于释放内存、关闭打开的文件、关闭网络连接等等,以防止资源泄漏和造成程序崩溃。当一个对象被删除或销毁时,析构函数会自动调用,以确保类能够正确地清理资源。 需要注意的是,当一个对象被复制时,也会调用构造函数析构函数。使用深拷贝和浅拷贝来管理类的复制,以确保不会复制对象的私有数据。此外,有一些 C++ 特殊语法,如移动语义和智能指针等等,可以用于提高构造函数析构函数的效率和安全性。 总之,构造函数析构函数是面向对象编程中不可或缺的两个概念。它们可以保证类的正确始化和释放,从而防止资源泄漏和程序崩溃。编写好构造函数析构函数是编写高质量 C++ 代码的关键。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值