面向过程—面向对象(C++的封装,this)_内存四区_变量生命周期
1、面向对象主要涉及 构造函数、析构函数、虚函数、继承、多态等。
2、对各种支持 的底层实现机制
c语言中,数据 和 处理数据的操作(函数) 是分开来声明,即语言本身并没有支持 “数据和函数”的关联性。
在C++中,通过抽象数据类型(abstract data type, ADT),在类中定义数据和函数,来实现数据和函数直接的绑定。
C++成员数据:static、nonstatic
C++成员函数:static、nonstatic、virtual
C++中的类class从面向对象理论出发,将变量(属性) 和 函数(方法)定义在一起,来描述现实世界中的类;但是从计算机的角度,程序依然由 数据段 和代码段构成。
C++编译器 如何完成 面向对象理论 到 计算机程序的转化?C++如何管理 类、对象以及两者之间关系?
当一个对象 调用 类时,C++编译器 如何区分 是哪个对象调用的哪个方法?
看个栗子:
#include "iostream"
using namespace std;
class C1
{
public:
int i;
int j;
int k;
protected:
private:
}; class C2
{
public:
int i;
int j;
int k;
static int m;
public: int getK() const {return k;}
void setK(itn val){k = val;}
protected:
private:
} struct S1
{
int i;
int j;
int k;
} struct S2
{
int i;
int j;
int k;
static int m;
} int main()
{
printf("C1: %d \n", sizeof(C1));
printf("C2: %d \n", sizeof(C2));
printf("S1: %d \n", sizeof(S1));
printf("S2: %d \n", sizeof(S2));
}
4个值都是12,结论:
属性(普通成员变量) 放在栈中;
静态属性(static variable)放在全局数据区;
方法 (成员函数) 放在代码区。
用this指针区分是哪个对象调用的公用方法,谁调用这个公用方法,就把谁的地址传递给this指针。
C++编译器对普通成员函数的内部处理:添加this指针的面向过程实现
看个栗子:
C++的类:
class Test
{
private:
int m1;
public:
Test(int i)
{
m1 - i;
}
int get1()
{
return m1;
}
static void Print() //静态成员函数属于整个类,不属于某个变量,没有this指针
{
printf("This is class Test. \n");
}
};
Test a();
a.get1();
Test::Print();
对应的面向过程的实现过程。
struct Test
{
int m1;
};
void Test_initialize(Test *pThis, int i)
{
pThis->m1 - i;
}
int Test_get1(Test *pThis)
{
return pThis->m1;
}
void Test_Print()
{
printf("This is class Test. \n");
}
};
Test a;
Test_initialize(&a, );
Test_get1(&a);
Test_Print();
结论:
1、C++类对象的 成员变量 和 成员函数 是分开存储的。C语言中的内存4区模型仍然有效;
2、C++中类的普通成员函数都隐式包含一个指向当前对象的this指针。
3、静态成员函数、静态成员变量属于类。静态成员函数不包含指向具体对象的指针,普通成员函数包含一个指向具体对象的指针。
有关内存四区模型:
内存四区模型:
流程说明
1、操作系统把物理硬盘代码load到内存
2、操作系统把c代码分成四个区
3、操作系统找到main函数入口执行

char*fa()
{
char*pa = "";//pa指针在栈区,“123456”在常量区,该函数调用完后指针变量pa就被释放了
char*p = NULL; //指针变量p在栈中分配4字节
p=(char*)malloc();//本函数在这里开辟了一块堆区的内存空间,并把地址赋值给p
strcpy(p, "wudunxiong 1234566");//把常量区的字符串拷贝到堆区
return p;//返回给主调函数fb(),相对fa来说fb是主调函数,相对main来说,fa(),fb()都是被调用函数
}
char*fb()
{
char*pstr = NULL;
pstr = fa();
return pstr;//指针变量pstr在这就结束
}
void main()
{
char*str = NULL;
str = fb();
printf("str = %s\n",str);
free(str); //防止内存泄露,被调函数fa()分配的内存存的值通过返回值传给主调函数,然后主调函数释放内存
str = NULL;//防止产生野指针
system("pause");
}
总结:
1、主调函数分配的内存空间(堆,栈,全局区)可以在被调用函数中使用,可以以指针作函数参数的形式来使用;
2、被调用函数分配的内存空间只有 堆区(指针 所指向的 内存区域) 和 全局区(静态变量 和 常量) 可以在主调函数中使用(返回值和函数参数),而栈区(指针存放的地址)却不行,因为栈区函数体运行完之后这个函数占用的内存编译器自动帮你释放了。
面向过程—面向对象(C++的封装,this)_内存四区_变量生命周期的更多相关文章
- php连接数据库的两种方式- 面向过程 面向对象
php连接数据库的两种方式- 面向过程 面向对象 一.面向对象1. 链接数据库$conn = @new mysqli("127.0.0.1","root", ...
- ArcGIS for Desktop入门教程_第四章_入门案例分析 - ArcGIS知乎-新一代ArcGIS问答社区
原文:ArcGIS for Desktop入门教程_第四章_入门案例分析 - ArcGIS知乎-新一代ArcGIS问答社区 1 入门案例分析 在第一章里,我们已经对ArcGIS系列软件的体系结构有了一 ...
- 【java基础】面向过程~面向对象
相信大家都知道这两个东西,可是大家是如何知道的呢?我们又该如何区分这个东西到底是面向过程还是面向对象的呢? 那,我们首先就要知道什么是面向过程,什么是面向对象: 面向过程"(Procedur ...
- 2017 5 31 php面向过程 面向对象1
面向过程的语法定义变量:定义函数:使用变量(输出,赋值,等)调用函数:流程控制(if,switch,for,while等) 面向对象的语法1,定义类:定义类的语法中,只有这3种代码:1.1定义属性(变 ...
- Python笔记_第四篇_高阶编程_再议装饰器和再议内置函数
1. 概述: 我们在前面用了很多的装饰器这个工具的方法.这个位置要系统的讲一下装饰器. 1.2 为什么需要装饰器. 装饰器本质是一个Python函数,它可以让其他函数在不需要任何代码变动的前提下增加额 ...
- .Net基础篇_学习笔记_第四天_关系运算符和逻辑运算符
1.关系运算符 包含:> < <= >= == != 以及bool类型中的true和false. 2.逻辑运算符 与 && 或 || 非 ! 注 ...
- .Net基础篇_学习笔记_第四天_加加减减
using System.Linq; using System.Text; using System.Threading.Tasks; namespace 第四天_加加减减 { class Progr ...
- Python笔记_第四篇_高阶编程_进程、线程、协程_5.GPU加速
Numba:高性能计算的高生产率 在这篇文章中,笔者将向你介绍一个来自Anaconda的Python编译器Numba,它可以在CUDA-capable GPU或多核cpu上编译Python代码.Pyt ...
- Python笔记_第四篇_高阶编程_二次封装
1.二次封装: 二次封装其实就是对一个类或者一个方法进行二次的改造增加新的功能. 2.一个类的二次封装: 我们以一个进程为例,我们把Process这个库进行二次封装,增加一些功能,在调用. thoma ...
随机推荐
- 廖雪峰js教程笔记3
JavaScript的函数在查找变量时从自身函数定义开始,从"内"向"外"查找.如果内部函数定义了与外部函数重名的变量,则内部函数的变量将"屏蔽&qu ...
- node入门 express ejs
hello.js var express = require("express"); var app = express(); app.get("/hello" ...
- JS 中面向对象的5种写法
//第1种写法 function Circle(r) { this.r = r; } Circle.PI = 3.14159; Circle.prototype.area = function() { ...
- Android HttpClient post MultipartEntity - Android 上传文件
转自[http://blog.csdn.net/hellohaifei/article/details/9707089] 在Android 中使用HttpClient,MultipartEntity ...
- Android Force Close的原因:
1.程序空指针: 2.程序加载的资源找不到: 3.未加载布局文件时直接使用了对象: 4.后台service挂掉导致不可捕捉的ANR或crash: 5.Activity未在配置文件中注册.
- Jquery和JS获取ul中li标签
js 获取元素下面所有的li var content=document.getElementById("content"); var items=content.getElemen ...
- soapui中文操作手册(五)----入门与安全测试
在SoapUI4.0引入的安全测试特点使它非常容易为你来验证你的目标服务的功能性安全,就可以评估您的系统常见的安全攻击的漏洞.特别是如果系统是公开可用的,即使不是这种情况,确保了完全安全的环境也是非常 ...
- django 后台管理
修改 admin.py from myapp.models import * from django.contrib import admin # Register your models here. ...
- CUDA程序设计(二)
算法设计:直方图统计 直方图频数统计,也可以看成一个字典Hash计数.用处不是很多,但是涉及CUDA核心操作:全局内存.共享内存.原子函数. 1.1 基本串行算法 这只是一个C语言练习题. #def ...
- Set集合对象比较两个元素的方法
Set集合对象比较两个元素的方法并不是根据“equals()”方法的返回值来比较.而是用“hashCode()”方法来进行判断.只要两个元素的“hashCode()”方法的返回值相同,就认为两个元素相 ...