C++学习第二课 第三节 C++和C语言中的struct;类

C语言中,我们可以使用结构体对数据进行打包封装。
比如:
头文件中

struct tagNode
{
	int nRow;
	int nCol;
};
void Position(tagNode* pNode, int nRow, int nCol);


cpp文件中

void Position(tagNode* pNode, int nRow, int nCol)
{
	pNode->nRow = nRow;
	pNode->nCol = nCol;
}

这样做的好处是,我们可以通过头文件就可以知道有哪些数据,以及操作数据的接口(函数)是什么。
但是它的不足之处是:

  • C语言中的结构体,大部分时候是用来封装数据,不包含动作。(通过函数指针可以实现封装数据和动作)
  • 生活中对事物的看法,往往是“数据”和“动作”一体的。
    比如,“人”,有高矮胖瘦、能跑跳等。

而面向对象中的“封装”,指的是,将数据和处理数据的动作封装在一起。
C++中,为了更好的表达封装,在C语言的基础上,改进了struct,提出了class

C++中的结构体

为了更好的表达面向对象的思想,C++中的结构体,在C的基础上做了改进。

  • C++的结构体中,可以定义函数(一般称为“方法”)
  • 方法可以直接使用结构体中的数据成员,而不需要通过参数列表传递。

定义方法

struct tagNode
{
	int nRow;
	int nCol;
	void SetPos(int argRow, int argCol)
	{
		nRow = argRow;
		nCol = argCol;
	}
	void ShowPos()
	{
		printf("%d,%d\r\n", nRow, nCol);
	}
};

方法的调用方式

  • 先声明一个C++结构体的变量(一般称为“对象”)
  • 可以像调用成员那样,利用“.”的调用方法。
    实例如下:
#include <iostream>

struct tagNode
{
	int nRow;
	int nCol;
	void SetPos(int argRow, int argCol)
	{
		nRow = argRow;
		nCol = argCol;
	}
	void ShowPos()
	{
		printf("%d,%d\r\n", nRow, nCol);
	}
};


int main(int argc, char* argv[])
{
	tagNode node1;
	node1.SetPos(10, 10);
	node1.ShowPos();

	node1.SetPos(20, 20);
	node1.ShowPos();
	return 0;
}

方法的原理

不同对象的同名方法,在汇编级别,是一样的。

int main(int argc, char* argv[])
{
	tagNode node1;
	tagNode node2;

	node1.SetPos(1, 1);
	node1.ShowPos();
	node2.SetPos(2, 2);
	node2.ShowPos();
	return 0;
}

通过以上代码发现,node1.SetPos和node2.SetPos是同一个方法(SetPos)。
既然是调用同一个方法,那么为什么设置结构体变量分别设置了node1和node2,并且node2不会覆盖node1呢?

要解答这个问题,就需要揭开这背后的秘密:C++中的this指针。

this是C语言中的关键字,代表指向当前对象的指针,实际上,刚刚所说的方法可以直接调用结构体中的成员,其实是因为C++编译器为每个成员自动加上了this->

void SetPos(int argRow, int argCol)
	{
		nRow = argRow;
		nCol = argCol;
	}

以上代码的实际样子其实是:

void SetPos(int argRow, int argCol)
	{
		this->nRow = argRow;
		this->nCol = argCol;
	}

this指针是如何传递的?

对于对象的方法调用,使用的调用约定不是C语言中的约定、stdcall等,而是使用了this调用约定。

C++中结构体方法的约定是thiscall
什么是thiscall?以微软编译器为例:
它会从右往左传参,this指针中保存的地址存放在ecx中,对象地址会通过**ecx(寄存器)**传递。

关于对象的方法调用的特殊之处

  • 采用thiscall约定
  • thiscall会自动传递一个this指针,this指针指向当前调用的对象的首地址。
  • 微软cl编译器,通过ecx寄存器传递this指针。

引出主角:类

C++中对C语言中struct的改进,使我们可以更好的面向对象,可以更方便的将数据和动作封装到一起,借助thiscall约定和this指针,也更不容易混淆需要操作的参数。
为了更加凸显C++中封装同C语言中的封装的区别,C++发明了关键字class
C++中的class和C++中的struct几乎是一样的,唯一的区别是默认访问权限不一样

  • 问题1:C语言和C++中的struct有什么不同?(封装)
  • 问题2:C++中的struct和class有什么不同?

默认访问权限

在C++中有三种权限

  • public:方法和成员可以被所有人使用
  • private:方法和成员只可以被当前类中的方法使用
  • protectd

当是struct时:

#include"stdafx.h"
#include <iostream>

struct tagNode
{
	int nRow;
	int nCol;
	void SetPos(int argRow, int argCol)
	{
		this->nRow = argRow;
		this->nCol = argCol;
	}
	void ShowPos()
	{
		printf("%d,%d\r\n", nRow, nCol);
	}
};


int main(int argc, char* argv[])
{
	tagNode node1;
	tagNode node2;

	node1.SetPos(1, 1);
	node1.ShowPos();
	node2.SetPos(2, 2);
	node2.ShowPos();
	return 0;
}

像以上这样做可以的,但是当struct换成class后:

#include"stdafx.h"
#include <iostream>

class tagNode
{
	int nRow;
	int nCol;
	void SetPos(int argRow, int argCol)
	{
		this->nRow = argRow;
		this->nCol = argCol;
	}
	void ShowPos()
	{
		printf("%d,%d\r\n", nRow, nCol);
	}
};


int main(int argc, char* argv[])
{
	tagNode node1;
	tagNode node2;

	node1.SetPos(1, 1);
	node1.ShowPos();
	node2.SetPos(2, 2);
	node2.ShowPos();
	return 0;
}


在这里插入图片描述
就会报以上错误。

更改:当在class下添加public后,就可以了。
在这里插入图片描述
结论:

  • class的默认访问权限是private
  • struct默认访问权限是public

权限管理的好处

权限管理可以使我们将一些不能修改的数据用private给予限制,防止被修改,保证了数据的安全。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值