C++面向对象——如何用oop编程、类和对象、this指针

本文介绍了C++面向对象编程的基本概念,包括OOP的四大特性:抽象、封装、继承和多态。重点讨论了如何在C++中实现封装,以及类和对象的使用。此外,还详细解释了this指针的作用,它是如何帮助成员方法区分不同对象并处理各自的数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++面向对象(oop) 如何用oop编程

(1)如何用OOP编程?

OOP语言的四大特征是什么?抽象 封装(隐藏) 继承 多态

怎么体现封装(隐藏):通过类的访问限定符:public 共有的 private 私有的 protected 保护的
在C中:定义各种各样的函数,struct可以自定义类型
在C++中:输出各种各样的类。类(给用户自定义类型的,描述为实体的抽象类型)在计算机世界里面的类来代表现实世界的实体的抽象类型。

用OOP的思想解决问题:
1、先找实体;
2、然后根据下面这个思维图,编写代码

ADT表示实体的抽象数据类型,分析出实体它有什么属性什么行为
在计算机的类里面,从实体属性得到的东西是类的成员变量;从实体行为得到的东西是类的成员方法。类并不代表实体,而是实体的ADT
当我用这个类型去实例化对象后(对象是占栈内存空间的,就类似实体在现实世界里面占据空间是一样的), 对象在逻辑意义上来代表现实世界中的实体

注意:
计算机语言也讲究语言美,在命名类时统一采取,驼峰式命名
调用成员方法时,C语言直接调用就好show(),C++还要加对象名good.show();
类型不占空间,用内存定义了对象才占用(栈)空间


const int NAME_LEN = 20;
//
class Goods //=》商品数据化类型,类型不占空间,用内存定义了对象才占用(栈)空间
{
public://给外部提供共有的方法,来访问实体私有的属性
	void init(const char *name, double price, int amount);
	//打印商品信息
	void show();
	//定义类成员方法,可以在类体内;处理时,自动处理成inline内联函数(复习)
	//给成员变量提供一组getXXX或setXXX的方法,使我们在外部调用这些接口后,就可以对相应的成员变量进行赋值。
	void setName(char *name) { strcpy(_name, name); }
	void setPrice(double price) { _price = price; }
	void setAmount(int amount) { _amount = amount; }

	//char *getName();//定义char* 接口,返回普通的char*类型(即,传回了私有成员具体某一个值的地址),导致外部可以直接修改内部成员的值;修改方法:前面加const
	const char *getName() { return _name; }
	double getPrice() { return _price; }
	int getAmount() { return _amount; }

private://属性一般都是私有的,不可访问
	char _name[NAME_LEN];
	double _price;
	int _amount;

};
//定义类成员方法,也可以在类外,但是要加上作用域,不然就称为全局方法了。
void Goods::init(const char *name, double price, int amount)//想让它也称为inline内联函数,就要在前面加inline;
{
	strcpy(_name, name);
	_price = price;
	_amount = amount;
}
void Goods::show()
{
	cout << "name:" << _name << endl;
	cout << "price:" << _price << endl;
	cout << "amount:" << _amount << endl;
}
int main()
{
	Goods good;//类实例化了一个对象
			   //cout << good._price << endl;//不能访问成员Coods::_price

	good.init("面包", 10.0, 20);//在新版vs编译器里面,常量字符串不允许用普通指针来接收,要用常指针(即,加const)
	good.show();
	system("pause");
	return 0;
}

char* name 为什么要加const?

void init(const char *name, double price, int amount);

因为在主函数中,在新版vs编译器里面,常量字符串不允许用普通指针来接收,要用常指针(即,加const)

good.init("面包", 10.0, 20);//在新版vs编译器里面,常量字符串不允许用普通指针来接收,要用常指针(即,加const)

定义类成员方法,也可以在类外,但是定义在域外,要加上作用域,不然就称为全局方法了;如果定义在域外,想让它也称为inline内联函数,就要在前面加inline,域内的成员方法默认为inline内联函数。

void Goods::init(const char *name, double price, int amount)

在主函数中,因为_pirce 是类的私有成员,所以不能直接访问。

cout << good._price << endl;//不能访问成员Coods::_price

如何计算对象的内存大小?
类似结构体的计算方式,对象的内存大小只依赖于成员变量,与成员方法的多少无关。算成员变量的大小是和结构体变量的内存计算方式一样:先找占用内存最长的成员变量,以其为内存字节对齐的方式。然后计算出总的对象的大小。

另一种方法:
在VS编译器里面 工具–>VS命令提示(不是win 的cmd)
1 打开所在的文件夹(当前想查看的类所在的路径)
在这里插入图片描述
2 然后cd + 路径名 打开这个路径:
在这里插入图片描述
3 输入dir:
在这里插入图片描述
4 输入cl cpp文件全称 /d1reportSingleClassLayout类名称
在这里插入图片描述
这个CGoods类的大小是40字节, 先是name 20字节。然后补4字节空白:最长的成员分量就是这
个double 8个字节(对象在排列的时候是以8字节对齐的)。一个char一个字节,所以为了补齐24字节(3*8=24 20+4=24);然后price8个字节,最后amount也是8个字节(4+4=8),所以最后就是(20+4+8+4+4)这两个加粗的4补齐加的空白,即40字节。

先看最长的成员分量占多少字节,以它为内存字节的对齐方式。不够的补齐。这个补位的目的:为了让内存字节对齐。字节对齐的最大优点:节省CPU在内存上访问数据的IO次数。(这个会在后面njax内存池上讲 内存对齐的东西)

注: 一个类可以定义无数个对象(不同的对象代表不同的实体),每一个对象都有自己的成员变量,但是他们共享一套成员方法(方法编译成指令是放在text段上的)。修改一个对象的成员变量不影响其他对象的成员变量。

当执行到第四步是可能会出现错误:
text.cpp c1xx: fatal error C1007: 无法识别的标志“-reporSingleClassLayoutGoods”(在“c1xx”中)
这个可能是你在安装vs的过程中,少了部分插件,点击“工具”——“获取工具或功能”,然后在“扩展开发”打钩,最后安装,这样就可以正常使用了。
在这里插入图片描述

this指针

问题:当用对象调用类里面的同一套方法时,这个方法是怎么知道处理哪个对象的信息呢?

//初始化
void init(const char *name, double price, int amount);//;怎么知道要给哪个对象初始化?
//打印商品信息
void show();//怎么知道处理哪个对象的信息?

为什么要this指针?
因为类可以定义无数个对象(不同的对象代表不同的实体),每一个对象都有自己的成员变量(他们之间互不冲突),但是他们共享一套成员方法(方法编译成指令是放在text段上的)。那么这一套的成员方法是如何区分对象的呢?这就是理解this指针的核心。

good.init("面包", 10.0, 20);

在调用函数时,加上对象名,相当于把调用这个方法的对象的地址给传进来了。这里和C没有什么区别:因为在汇编上只有函数调用,call指令等等。(汇编是不存在什么OOP的)对象调用成员方法,转变成了C的调用方式:把调用这个方法的对象的地址给传进来。
既然你传进去一个实参(地址实参),那么你就需要添加一个形参(this指针)来接收。good1是Goods类型, **所以当编译器在给类的成员方法一编译以后,会给所有的成员方法 参数 都加上一个this 指针 来接收调用这个方法的对象的地址。**但是我们可以不用写这个。

那么这一套的成员方法是如何区分对象的呢?
因为当用对象调用这些方法的时候,把调用这个方法的对象的地址通过实参给传给这些函数,这些函数就会使用一个在编译器在给类的成员方法一编译以后,会给所有的成员方法 参数 都加上一个this 指针 来接收调用这个方法的对象的地址。

在编译过程中,编译器会给成员方法 成员变量自动加上一个 this指向。(可以不加)

this指针的作用:在成员方法里面去区分当前类的不同对象,以处理不同对象的数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值