类和对象【超详细】

预学先知

①面向对象和面向过程的初步认识
C语言是面向过程,关注的是过程,分析步骤,利用函数调用解决问题
C++是基于面向对象的,关注的是对象,将一件事拆成不同的对象,靠对象的交互完成
例子:
设计一个快递系统
面向过程:关注实现下单,信息整合,送单的过程,体现到代码–方法/函数
面向对象:关注实现类对象及类对象之间的关系,快递员,商家,用户之间的关系 --类的设计及类之间的关系

②C++是基于面向对象:面向过程和面向对象混编。
原因:C++兼容C
然而JAVA是纯面向对象:只有面向对象

③C++对结构体进行了升级
一方面struct 在C++中升级成了类
C++类跟结构体不同的是除了可以定义变量,还可以定义方法/函数

#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<cstdio>
using namespace std;

//struct/class
//C++兼容C中结构体的用法
//同时Struct在c++中升级成了类
//C++在类中还可以定义方法/函数
struct Student {
   
	//成员变量
	char _name[10];
	int _age;
	int _id;

	//成员方法
	void Init(const char* name, int age, int id) {
   //避免冲突,将前面改成_
		strcpy(_name, name);
		_age = age;
		_id = id;
	}
	void Print() {
   
		cout << _name << " " << _age << " " << _id << endl;
	}
};
int main() {
   
	struct Student s1 = {
   "xpc",18,7};//兼容C
	Student s2 = {
     };  //升级成为类,Student是类名,也是类型
	
	s1.Print();
	s2.Init("zkx", 20, 11);
	s2.Print();
	return 0;
}

类和对象

1.类的访问限定符

了解class 和 struct 定义的区别,class 里面成员变量默认是私有的,而struct默认是公有(public)
在这里插入图片描述
最好不要使用默认限定,自己定义private和public(访问限定符)
我们来定义第一个类~
封装是一种更好的管理模式
①数据和方法都封装到类里面
②可以给你访问定义成共有,不想给你访问定义成私有或者保护
不封装是一种自由管理

class Student {
   
private:
	//成员变量
	char _name[10];
	int _age;
	int _id;
public:
	//成员方法
	void Init(const char* name, int age, int id) {
   //避免冲突,将前面改成_
		strcpy(_name, name);
		_age = age;
		_id = id;
	}
	void Print() {
   
		cout << _name << " " << _age << " " << _id << endl;
	}
};
int main() {
   
	struct Student s1; //兼容C
	Student s2;  //升级成为类,Student是类名,也是类型
	
	return 0;
}

注意,如果加了inline或者直接在类内定义(10几行内),编译器可能将这个方法当成内联函数处理
在这里插入图片描述

2.类的作用域

类定义了一个域
在这里插入图片描述

3.类大小的计算

只保存成员变量,成员函数放在公共代码区

为什么成员函数不放进来计算?
原因:每个对象中都有独立的成员变量,不同对象调用成员函数,调的是同一个,没有必要每个对象都保存一份

结论:计算类和类对象的大小,只看成员变量,考虑内存对齐,C++内存对齐规则跟C语言一致

另外,空类会给1byte,不存储有效数据,只是为了占位表示对象的存在
sizeof 类 算出的是实例化对象的大小,而不是类是多大
在这里插入图片描述
补充C语言的内存对齐规则
在这里插入图片描述

4.this指针

既然成员方法不保存在类的实例对象内,那这些不同的对象调用同样的方法为什么会取得他们各自的值??
那是因为省略了隐藏的this指针!

①调用成员函数时,不能显示传实参给this
②定义成员函数时,也不能显示声明形参this
③在成员函数内部,我们可以显示使用this
在这里插入图片描述

问题1:this是存在哪的?
一般情况下是存在栈(形参),有些编译器会放到寄存器中,如VS2019,ecx
问题2:
在这里插入图片描述
这道题选C
如果有人觉得是空指针错了,那不行,空指针是运行时错误,编译是检查不出来的

问题3:
在这里插入图片描述
选B

5.默认成员函数

在这里插入图片描述
1.构造函数
在这里插入图片描述

不然既有全缺省又有无参,语法上可以同时存在,但是如果同时存在,就会产生二义性


class Date {
   
public:
	/*Date() {
		_year = 2022;
		_month = 2;
		_day = 8;
	}
	Date(int year, int month, int day) {
		_year = year;
		_month = month;
		_day = day;
	}*/
	
	//推荐使用全缺省或者半缺省,比较好用
	Date(int year = 2022, int month = 2, int day = 8) {
   
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main() {
   
	Date d1;
	Date d2(2022);
	Date d3(2022, 1);
	Date d4(2022, 1, 15);

	return 0;
}

C++把类型分成两类:内置类型(基本类型),自定义类型
内置类型:int/char/double/指针/内置类型数组等
自定义类型:struct/class定义的类型

我们不写编译器默认生成构造函数,对于内置类型不做初始化处理
对于自定义类型成员变量会去调用它的默认构造函数(不用参数就可以调的)初始化
如果没有默认构造函数就会报错
任何一个类的默认构造函数就是–不用参数就可以调用
有三个,全缺省,无参,我们不写编译器默认生成的

总结:C++我们不写编译器默认生成构造函数,设计得不好,没有对内置类型和自定义类型统一处理
不处理内置类型的成员变量,只处理自定义类型成员变量

#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<cstdio>
using namespace std;


class A {
   
public:
	A(int a = 0){
   
		cout << "a()" << endl;
		_a= a;
	}
private:
	int _a = 0;
};

class Date {
   
public:

private:
	int _year;
	int _month;
	int _day;
	A _aa;
};

int main() {
   
	Date d1;
	

	return 0;
}

构造函数本质用来初始化
在这里插入图片描述
构造函数的初始化列表
用: 和 , 分割
弄懂声明和定义:声明是一种承诺,没有实现,没有开空间,类型+变量属于是声明,定义是要开空间,要给值
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值