【C++类和对象Lesson1】面向对象、类的初步认识、this指针详解

81 篇文章 2 订阅
65 篇文章 4 订阅
这篇博客主要介绍了C++的面向对象编程基础,包括封装、类、访问权限、struct与class的区别、类的作用域、实例化以及对象模型。此外,还详细讲解了this指针的特性和用途,以及如何处理空指针调用成员函数的情况。内容适合C++初学者复习和巩固面向对象的基础概念。
摘要由CSDN通过智能技术生成

朋友们好,这篇播客我们继续C++的初阶学习,现在对一些C++的入门知识做了些总结,整理出来一篇博客供我们一起复习和学习,如果文章中有理解不当的地方,还希望朋友们在评论区指出,我们相互学习,共同进步!

什么是面向对象?
在这里插入图片描述

一:面向对象的初步认识

C++面向对象的三大特性为:封装、继承、多态

C++认为万事万物都皆为对象,对象上有其属性行为
例如:
人可以作为对象,属性有姓名、年龄、身高、体重…,行为有走、跑、跳、吃饭、唱歌…

​车也可以作为对象,属性有轮胎、方向盘、车灯…,行为有载人、放音乐、放空调…

​具有相同性质的对象,我们可以抽象称为类,人属于人类,车属于车类

面向对象编程思想还需要我们在学习过程中不断的理解!

1.1:封装

封装是C++面向对象的三大特征之一,将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互
封装的意义:

  1. 将属性和行为作为一个整体,表现生活中的事物
  2. 将属性和行为加以权限控制

1.2:类的引入

在设计类的时候,属性和行为写在一起,表现事物,语法: class 类名{ 访问权限: 属性 / 行为 };
例如设计一个圆类:

class Circle
{
public:  //访问权限  公共的权限

	//属性
	int m_r;//半径

	//行为
	//获取到圆的周长
	double calculateZC()
	{
		//2 * pi  * r
		//获取圆的周长
		return  2 * PI * m_r;
	}
};

类的两种定义方式:

  1. 声明和定义全部放在类体中,需要注意:成员函数如果在类中定义,编译器可能会将其当成内联函数处理。
  2. 声明放在.h文件中,类的定义放在.cpp文件中。

注:声明和定义的区别是有无开辟空间。

1.3:类的访问权限

类在设计时,可以把属性和行为放在不同的权限下,加以控制。

  • public 公共权限
  • protected 保护权限
  • private 私有权限

三种权限的区别:
公共权限 public 类内可以访问 类外可以访问
保护权限 protected 类内可以访问 类外不可以访问
私有权限 private 类内可以访问 类外不可以访问
示例:

class Person
{
	//姓名  公共权限
public:
	string m_Name;

	//汽车  保护权限
protected:
	string m_Car;

	//银行卡密码  私有权限
private:
	int m_Password;

public:
	void func()
	{
		m_Name = "张三";
		m_Car = "拖拉机";
		m_Password = 123456;
	}
};

int main() {

	Person p;
	p.m_Name = "李四";
	//p.m_Car = "奔驰";  //保护权限类外访问不到
	//p.m_Password = 123; //私有权限类外访问不到

	system("pause");
	return 0;
}

m_Car、m_Password分别为保护权限和私有权限,在类外不可直接访问。
访问权限符说明:

  1. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现为止。
  2. class默认权限为private,struct默认权限为public(因为struct要兼容C)。

注意:访问限定符只在编译的时候有用,当数据映射到内存后,没有任何访问限定符的区别。

1.4:struct和class的区别

在C++中 struct和class唯一区别就在于 默认的访问权限不同
区别:

  • struct 默认权限为公共。
  • class 默认权限为私有。

示例:

class C1
{
	int  m_A; //默认是私有权限
};

struct C2
{
	int m_A;  //默认是公共权限
};

int main() {

	C1 c1;
	c1.m_A = 10; //错误,访问权限是私有

	C2 c2;
	c2.m_A = 10; //正确,访问权限是公共

	system("pause");

	return 0;
}

都在默认权限时,c1.m_A访问不到,c2.m_A可以访问。

1.5:类的作用域

类定义了一个新的作用域,类的所有成员都在类的作用域中。在类外定义成员,需要使用::作用域解析符指明成员属于哪个类域
示例:

class Circle
{
public:  //访问权限  公共的权限

	//属性
	int m_r;//半径

	//行为
	//获取到圆的周长
	double calculateZC();
};

double Circle::calculateZC()
{
	//2 * pi  * r
	//获取圆的周长
	return  2 * PI * m_r;
}

1.6:类的实例化

类作为一种自定义类型,同样可以定义变量,用类类型创建对象的过程,称为类的实例化。
一个类可以实例化出多个对象,实例化出的对象,占用实际的物理空间,存储类非静态成员变量。

1.7:类对象模型

类中既可以有成员变量,又可以有成员函数,那么一个类的对象中包含了什么?如何计算一个类的大小?
在C++中,类内的成员变量和成员函数分开存储!!!
因为如果类实例化多个对象,那么在每个对象中都会保存一份代码,相同的代码保存多次,浪费空间,所以就分开存储。
只有非静态成员变量才属于类的对象上!,其他的成员函数,静态成员变量,静态成员函数都不在类对象上。
在这里插入图片描述
结论:一个类的大小,实际就是该类中“成员变量”之和,也要遵循内存对齐注意空类的大小,编译器给了空类一个字节来唯一标识这个类
总结:没有成员变量的类对象,编译会给他们分配1byte占位,表示对象存在过

class Person {
public:
	Person() {
		mA = 0;
	}
	//非静态成员变量占对象空间
	int mA;
	//静态成员变量不占对象空间
	static int mB;
	//函数也不占对象空间,所有函数共享一个函数实例
	void func() {
		cout << "mA:" << this->mA << endl;
	}
	//静态成员函数也不占对象空间
	static void sfunc() {
	}
};

int main() {
	cout << sizeof(Person) << endl;

	system("pause");
	return 0;
}

二:this指针

我们知道在C++中成员变量和成员函数是分开存储的,每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码
那么问题是:这一块代码是如何区分哪个对象调用自己的呢?
c++通过提供特殊的对象指针,this指针,解决上述问题。即:C++编译器给每个非静态的成员函数增加一个隐藏的指针参数,让该指针指向当前对象,在函数体中所有成员变量的操作,都是通过该指针去访问。只不过所有的操作都是对用户透明的,即用户不需要来传递,编译器自动完成

2.1:this指针的特性

  • this指针的类型:类类型 *const
  • 只能在“成员函数”的内部使用;
  • this指针本质上其实是一个成员函数的形式参数,是对象调用成员函数时,将对象地址作为实参传给this形参,所以对象中不存储this指针(this指针多数情况存在栈区,少数情况存在寄存器)
  • this指针是成员函数第一个隐含的指针形参,一般情况有编译器通过exc寄存器自动传递,不需要用户传递。
    在这里插入图片描述

2.2:this指针的用途

  • 当形参和成员变量同名时,可用this指针来区分。
  • 在类的非静态成员函数中返回对象本身,可使用return *this(注意函数返回类型要写 类名 &)。
class Person
{
public:

	Person(int age)
	{
		//1、当形参和成员变量同名时,可用this指针来区分
		this->age = age;
	}

	Person& PersonAddPerson(Person p)
	{
		this->age += p.age;
		//返回对象本身
		return *this;
	}
	int age;
};

void test01()
{
	Person p1(10);
	cout << "p1.age = " << p1.age << endl;

	Person p2(10);
	p2.PersonAddPerson(p1).PersonAddPerson(p1).PersonAddPerson(p1);
	cout << "p2.age = " << p2.age << endl;
}

int main() {

	test01();
	system("pause");
	return 0;
}

2.3:空指针访问成员函数

C++中空指针也是可以调用成员函数的,但是也要注意该成员函数有没有用到非静态成员变量,如果用到需要对this指针加以判断保证代码的健壮性
为什么空指针可以访问成员函数呢?
理解:因为成员函数并没有存在类对象的空间上,而是在公共代码区,编译链接的时候只会利用函数名去找地址,所以不存在对空指针的解引用

//空指针访问成员函数
class Person {
public:

	void ShowClassName() {
		cout << "我是Person类!" << endl;
	}

	void ShowPerson() {
		if (this == NULL) {
			return;
		}
		cout << mAge << endl;
	}

public:
	int mAge;
};

void test01()
{
	Person * p = NULL;
	p->ShowClassName(); //空指针,可以调用成员函数
	p->ShowPerson();  //但是如果成员函数中用到了this指针,就不可以了
}

int main() {

	test01();
	system("pause");
	return 0;
}

上述代码中,如果成员函数中用到了this指针,需要对this指针加以判断以增强代码的健壮性!

评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值