【跟学C++】C++类与对象—构造函数—析构函数(Study10)


 ============================ 【说明】 ===================================================
  大家好,本专栏主要是跟学C++内容,自己学习了这位博主【 AI菌】的【C++21天养成计划】,讲的十分清晰,适合小白,希望给这位博主多点关注、收藏、点赞。
  主要针对所学内容,通过自己的理解进行整理,希望大家积极交流、探讨,多给意见。后面也会给大家更新,其他一些知识。若有侵权,联系删除!共同维护网络知识权利!
 =======================================================================================

1、面向对象(类与对象)

  学过java应该知道,java一种面向对象的编程语言,C++也不例外,C++也是一种面向对象的语言。那么什么是面向对象,什么又是类,我们通过一个简答案例说明。
在这里插入图片描述

  我们利用程序来模拟飞机,首先飞机具有相关属性,例如名称,型号,产地等等;
  除此之外,还有其他功能,例如:起飞、降落、载客等等,我们可以把这些能做的事统称为方法
  在程序中,我们可以定义某种结构,这种结构包括飞机属性及飞机能做的功能,来简单模拟一架飞机,这种结构就是类方法就是属于该类的函数。

1.1 类

  上述所谓的结构可以统称为类,主要包括两部分:属性和方法。
  在使用时,我们必须要声明类,声明类时注意以下几点:
  (1)必须使用关键词class,在class后面定义一个类名。
  (2)在{}内定义相关属性和方法(函数)
  (3)注意分号(;)不要忘。
  我们简单声明一个类:

#include<iostream>
using namespace std;

class Plane{
	//属性
	string Nmae; //名称
	int Type; //型号
	string place;//产地

	//方法
	void Fly();//起飞
	void Descend();//降落

};

  上述案例中,我们利用class关键字创建了名为Plane的类,也可以理解为Plane是我们创建的一个数据类型,并在内部封装了属性和方法。

封装:封装是将数据和使用该数据的方法进行逻辑组合,这是面向对象编程重要特征之一(其他是抽象、继承、多态)。

1.2 对象

  纸上谈兵,类就像是张规划好的纸,声明类不会对成对执行有任何影响,就如同声明一个函数不去调用,那么函数也只是一个摆设。
  在程序中,对象时类的实际化。要利用类中各类功能(方法),就要实例化一个对象,并通过这个对象访问类的属性和方法,那这里的对象就好比不同型号的飞机,比如歼击机-20,侦察机等等,这些实例基本都具有类中的属性和方法。
  实例化一个对象,就如同声明一个变量,前面说了我们声明的类Plane就是我们创建的一个数据类型,例如:

int a=0;//声明一个变量、
Plane J-20;实例化一个对象J-20

  之前,在【跟学C++】C/C++必学知识——指针【番外2】中学习过,利用new关键字来为数据动态分配内存,同时利用delete释放内存。

int *pNum = new int;
delete pNum;

  在这里,我们也可以利用自己创建的数据类型Plane,利用new来为Plane的对象动态分配内存空间。

//动态分配内存给Plane对象。new返回分配的内存地址给指针pPlane,也可以说pPlane指向分配的内存
Plane *pPlane=new Plane;
delete pPlane;
1.3 访问之句点运算符(.)

  前面讲了,我们实例化对象,可以访问类的属性和方法,那么我们该如何或者说利用什么方式去访问呢?
  第一种方式,我们可以利用句点运算符(.),可以访问属性和成员函数,例如上面的Plane类,实例化一个对象J-20,可以利用句点访问类的属性和方法:

Plane J-20;
J-20.Name="歼-20";
J-20.Fly();//访问函数

  另外,当有一个指针pJ-20,指向Plane类的实例对象J-20,也可以利用句点访问:

Plane *pJ-20=new Plane();
(*pJ-20).Fly();
1.4 访问之指针运算符(->)

  想要使用指针运算符->来访问属性和方法是有条件的,对象是通过new在自由存储区中示例化,或者有指向对象的指针,那么这样可以利用指针运算符->来访问成员属性和方法。

  1、通过new来在存储区中实例化对象:

Plane *pJ-20=new Plane();
pJ-20->Nmae="歼-20";
pJ-20->Fly();
delete pJ-20;

  2、指针指向对象:

Plane J-20;
Plane *pJ-20=&J-20;
pJ-20->Nmae="歼-20";
pJ-20->Fly();
delete pJ-20;

2、public(公有)和private(私有)

  实际中,很多信息是保密的,为了将这些数据隐私不公开,在类中我们可以利用public(公有)和private(私有)关键字来定义属性和方法。
  公有属性和方法只要有需要就可以利用对象来访问,私有属性和方法若想访问,只能在类的内部(或其友元)中访问。
  比如一个案例,飞机的型号是不公开的,私密的,因此Type作为私有属性,当你想向外部提飞机型号,可以利用公有方法setType中,将型号值-10输出。

#include<iostream>
using namespace std;

class Plane{
private:

	int Type; //型号

public:

	void GetType(int inputType) {
		Type = inputType;

	}
	int setType(){
		return Type - 10;

	}

};

int main() {
	Plane J20;
	J20.GetType(66);


	Plane J30;
	J30.GetType(88);


	cout << "J20的型号为:" << J20.setType()<< endl;
	cout << "J30的型号为:" << J30.setType() << endl;

	return 0;
}

在这里插入图片描述

  如果使用句点运算符J20.Type访问时,程序会报错,原因是Type是私有属性,无法从外部直接访问。

3、构造函数

  构造函数是一种特殊的函数(方法),在创建对象时被调用。

3.1 声明与实现构造函数

  构造函数有两个特点:
  (1) 函数名与类名相同
  (2) 函数不返回任何值
  构造函数有两种构造方式:可以在类中,也可以在类外。
  案例

#include<iostream>
using namespace std;
class Human{
public:
	Human() {
		//函数体;
	}
};

class Human {
public:
	Human();//构造函数声明
};

Human::Human() {//定义构造函数
	//函数体;
};

  注意:(::)表示作用域运算符

3.2 使用构造函数

  构造函数是在创建函数时被调用,构造函数让类成员变量初始化的理想场所。
  案例:使用构造函数为类成员变量赋值。

#include<iostream>

using namespace std;

class Human
{
private:
	string Name;
	int Age;

public:
	Human()
	{
		cout << "构造函数:初始化变量Age" << endl;
		Age = 0;
	}
	void SetName(string InputName)
	{
		Name = InputName;
	}
	void SetAge(int InputAge)
	{
		Age = InputAge;
	}
	void Introduce()
	{
		cout <<"I am " << Age << " years old" << endl;
	}
};

int main()
{
	Human Man;
	Man.SetName("Jack");
	Man.SetAge(18);

	Man.Introduce();
	return 0;
}
3.3 重载构造函数
class Human
{
public:
	Human()
	{
		默认构造函数;
	}
	Human(string InputName)
	{
		重载构造函数;
	}
}

  案例

#include<iostream>
using namespace std;

class Human
{
private:
	string Name;
	int Age;
	
public:
	Human()
	{
		cout<<"调用构造函数:初始化变量Age"<<endl;
		Age=0;
	}
	Human(string InputName)
	{
		cout<<"调用重载构造函数1:初始化变量Name"<<endl;
		Age = 0; 
		Name= InputName; 
	}
	Human(string InputName, int InputAge)
	{
		Name = InputName;
		Age = InputAge;
		cout<<"调用重载构造函数2:初始化变量Age、Name"<<endl;
	}
	void SetName(string InputName)
	{
		Name = InputName;
	} 
	void SetAge(int InputAge)
	{
		Age = InputAge;
	}
	void Introduce()
	{
		cout<<"I am " + Name<< " and am "<<Age<<" years old"<<endl<<endl;;
	}
};

int main()
{
	Human Man;  //实例化对象
	Man.SetName("Jack");
	Man.SetAge(18);
	Man.Introduce();
	
	Human Woman("Lucy");  //实例化对象,并提供了一个参数
	Woman.SetAge(16);
	Woman.Introduce();
	
	Human Kid("Tom", 6);   //实例化对象,并提供了两个参数
	Kid.Introduce();
	return 0; 
}

3.4 带默认值的构造函数
class Human()
{
private:
	string Name;
	int Age;
public:
	Human(string InputName, int InputAge=18)
	{
		Name = InputName;
		Age = InputAge;
	}
};

Human Man("Tom");
Human Woman("Lucy", 16); //这时16就会覆盖默认值

  

4、析构函数

  与构造函数一样,析构函数也是一-种特殊的函数。 不同的是,析构函数在对象销毁时自动被调用。
  其声明方式和构造函数也近似,只是在前面加了一个波浪号(~) 。如下所示:

1.类内声明
class Human
{
public:
	~Human()
	{
		析构函数;
	}
}2.类外声明
class Human
{
public:
	~Human();
};
Human::~Human()
{
	构造函数;
}

  什么时候使用析构函数?
  每当对象不再在作用域内或通过delete被删除,进而被销毁时,都将调用析构函数。这使得析构函数是重置变量、释放动态分配内存和其他资源的理想场所
  注意:在对象创建时,编译器会自动调用构造函数;对象销毁时,将自动调用析构函数。
  构造函数、析构函数都是编译器自动调用的。

  

5、总结

  最后,长话短说,大家看完就好好动手实践一下,切记不能三分钟热度、三天打鱼,两天晒网。大家也可以自己尝试写写博客,来记录大家平时学习的进度,可以和网上众多学者一起交流、探讨,我也会及时更新,来督促自己学习进度。一开始提及的博主【AI菌】,个人已关注,并订阅了相关专栏(对我有帮助的),希望大家觉得不错的可以点赞、关注、收藏

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cqy阳

预祝上岸,感谢打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值