C++ -01- 封装 /类 /成员函数

C++是对C语言的拓展,C语言原有的语法C++都支持,并在此基础上添加了新的语法:封装、继承、多态、模板...
C语言与C++的主要区别应该就是:C++让编译器干了更多的事情

结构体可以做参数传递吗?
#include "stdafx.h"
#include 
#include 
#include 
struct Student
{
	int a;
	int b;
	int c;
	int d;
};

int Plus(Student s)
{
	return s.a + s.b + s.c + s.d;
}

int main(int argc, char* argv[])
{
	Student s = {1,2,3,4};
	int r = Plus(s);
	printf("r = %d\r\n",r);
        return 0;
}

分析这个函数是如何传递参数的:
我们知道数组传递的是一个指针,那结构体是否也一样呢?
由反汇编代码可知,结构体是内存复制的方式传递参数,因为结构体到底有几个成员,计算机并不知道,所以直接在堆栈给申请了一片空间存放。因此结构体可以当作参数来传递,但是如果结构体成员比较多的话,大量内存复制导致效率低。

int main(int argc, char* argv[])
20:   {
0040D700 55                   push        ebp
0040D701 8B EC                mov         ebp,esp
0040D703 83 EC 54             sub         esp,54h
0040D706 53                   push        ebx
0040D707 56                   push        esi
0040D708 57                   push        edi
0040D709 8D 7D AC             lea         edi,[ebp-54h]
0040D70C B9 15 00 00 00       mov         ecx,15h
0040D711 B8 CC CC CC CC       mov         eax,0CCCCCCCCh
0040D716 F3 AB                rep stos    dword ptr [edi]
21:       Student s = {1,2,3,4};
0040D718 C7 45 F0 01 00 00 00 mov         dword ptr [ebp-10h],1
0040D71F C7 45 F4 02 00 00 00 mov         dword ptr [ebp-0Ch],2
0040D726 C7 45 F8 03 00 00 00 mov         dword ptr [ebp-8],3
0040D72D C7 45 FC 04 00 00 00 mov         dword ptr [ebp-4],4
22:       int r = Plus(s);
0040D734 83 EC 10             sub         esp,10h
0040D737 8B C4                mov         eax,esp
0040D739 8B 4D F0             mov         ecx,dword ptr [ebp-10h]
0040D73C 89 08                mov         dword ptr [eax],ecx//栈顶存入1
0040D73E 8B 55 F4             mov         edx,dword ptr [ebp-0Ch]
0040D741 89 50 04             mov         dword ptr [eax+4],edx//栈顶下移4个字节
0040D744 8B 4D F8             mov         ecx,dword ptr [ebp-8]
0040D747 89 48 08             mov         dword ptr [eax+8],ecx
0040D74A 8B 55 FC             mov         edx,dword ptr [ebp-4]
0040D74D 89 50 0C             mov         dword ptr [eax+0Ch],edx
0040D750 E8 B5 38 FF FF       call        @ILT+5(Plus) (0040100a)
0040D755 83 C4 10             add         esp,10h
0040D758 89 45 EC             mov         dword ptr [ebp-14h],eax
23:       printf("r = %d\r\n",r);
0040D75B 8B 45 EC             mov         eax,dword ptr [ebp-14h]
0040D75E 50                   push        eax
0040D75F 68 1C 20 42 00       push        offset string "const = %d  #define = %d\r\n" (0042201c)
0040D764 E8 07 39 FF FF       call        printf (00401070)
0040D769 83 C4 08             add         esp,8
24:
25:       return 0;
0040D76C 33 C0                xor         eax,eax
26:   }
0040D76E 5F                   pop         edi
0040D76F 5E                   pop         esi
0040D770 5B                   pop         ebx
0040D771 83 C4 54             add         esp,54h
0040D774 3B EC                cmp         ebp,esp
0040D776 E8 75 39 FF FF       call        __chkesp (004010f0)
0040D77B 8B E5                mov         esp,ebp
0040D77D 5D                   pop         ebp
0040D77E C3                   ret


功能改进

直接传递结构体,会导致效率低下,那直接传递一个指针

struct Student
{
	int a;
	int b;
	int c;
	int d;
};
int Plus(Student* s)
{
	return s->a + s->b + s->c + s->d;
}
int main(int argc, char* argv[])
{
	Student s = {1,2,3,4};
	int r = Plus(&s);
	printf("r = %d\r\n",r);
	return 0;
}
00401070 55                   push        ebp
00401071 8B EC                mov         ebp,esp
00401073 83 EC 54             sub         esp,54h
00401076 53                   push        ebx
00401077 56                   push        esi
00401078 57                   push        edi
00401079 8D 7D AC             lea         edi,[ebp-54h]
0040107C B9 15 00 00 00       mov         ecx,15h
00401081 B8 CC CC CC CC       mov         eax,0CCCCCCCCh
00401086 F3 AB                rep stos    dword ptr [edi]
21:       Student s = {1,2,3,4};
00401088 C7 45 F0 01 00 00 00 mov         dword ptr [ebp-10h],1
0040108F C7 45 F4 02 00 00 00 mov         dword ptr [ebp-0Ch],2
00401096 C7 45 F8 03 00 00 00 mov         dword ptr [ebp-8],3
0040109D C7 45 FC 04 00 00 00 mov         dword ptr [ebp-4],4
22:       int r = Plus(&s);
004010A4 8D 45 F0             lea         eax,[ebp-10h]//只获取了首地址
004010A7 50                   push        eax//压栈
004010A8 E8 58 FF FF FF       call        @ILT+0(Plus) (00401005)
004010AD 83 C4 04             add         esp,4
004010B0 89 45 EC             mov         dword ptr [ebp-14h],eax
23:       printf("r = %d\r\n",r);
004010B3 8B 4D EC             mov         ecx,dword ptr [ebp-14h]
004010B6 51                   push        ecx
004010B7 68 1C 20 42 00       push        offset string "r = %d\r\n" (0042201c)
004010BC E8 2F 00 00 00       call        printf (004010f0)
004010C1 83 C4 08             add         esp,8
24:       return 0;
004010C4 33 C0                xor         eax,eax
25:   }
004010C6 5F                   pop         edi
004010C7 5E                   pop         esi
004010C8 5B                   pop         ebx
004010C9 83 C4 54             add         esp,54h
004010CC 3B EC                cmp         ebp,esp
004010CE E8 9D 00 00 00       call        __chkesp (00401170)
004010D3 8B E5                mov         esp,ebp
004010D5 5D                   pop         ebp
004010D6 C3                   ret


封装

#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>

struct Student
{
	int a;
	int b;
	int c;
	int d;
	int Plus()
	{
	    return a + b + c + d;
	}
};
int main(int argc, char* argv[])
{
	Student s = {1,2,3,4};
	int r = s.Plus();
	printf("r = %d\r\n",r);
	return 0;
}

和之前的代码对比一下,可以发现代码简洁了。封装就是把函数写在了结构体里面。调用时默认传入结构体的首地址。可以直接使用结构体里面的变量,不用定义指针来取



带函数的结构体称为类…………

成员函数

结构体里面的函数,称为成员函数。他虽然是成员,也在结构体里面,可它不占用结构体空间。