C++编译器对属性和方法的处理机制

C++中的class从面向对象理论出发,将变量(属性)和函数(方法)集中定义在一起,用于描述现实世界中的类。从计算机的角度,程序依然由数据段和代码段构成。

C++编译器如何完成面向对象理论到计算机程序的转化?

换句话:C++编译器是如何管理类、对象、类和对象之间的关系

具体的说:具体对象调用类中的方法,那,c++编译器是如何区分,是哪个具体的类,调用这个方法?

demo

#include <iostream>

using namespace std;

class C1
{
public:
	int i;  //4
	int j; //4
	int k;  //4
protected:
private:
}; // 大小应该是12

class C2
{
public:
	int i; //4
	int j; //4
	int k; //4

	static int m; //4
public:
	int getK() const { return k; } //4
	void setK(int val) { k = val; }  //4

protected:
private:
}; //大小可能是12,可能是16,可能是24 

struct S1
{
	int i;
	int j;
	int k;
}; // 大小是12

struct S2
{
	int i;
	int j;
	int k;
	static int m;
}; // 大小可能是12,可能是16

int main()
{
	printf("c1:%d \n", sizeof(C1)); // 结果是12
	printf("c2:%d \n", sizeof(C2)); // 结果是12
	printf("s1:%d \n", sizeof(S1)); // 结果是12
	printf("s2:%d \n", sizeof(S2)); // 结果是12

}

通过上面的demo,我们可以的得出:

1)C++类对象中的成员变量和成员函数是分开存储的

成员变量:

普通成员变量:存储于对象中,与struct变量有相同的内存布局和字节对齐方式

静态成员变量:存储于全局数据区中

成员函数:存储于代码段中。

问题出来了:很多对象共用一块代码?代码是如何区分具体对象的?

换句话说:int getK() const { return k; },代码是如何区分,具体obj1、obj2、obj3对象的k值?

看下图

对于普通成员函数,C++编译器做了一层封装,比如Test类的构造函数,其中虽然只写了一个参数i,但实际上就像右面结构体的初始化函数那样,类的构造函数隐藏定义了一个this指针。

而静态成员函数,不需要this指针,因为是共用的,对于类只需要标注作用域就可以了。

所以执行Test a(10); 就相当于 Test a; Test_initialize(%a, 10);其他的类似对比就懂了。

总结:

1、C++类对象中的成员变量和成员函数是分开存储的。C语言中的内存四区模型仍然有效!

2、C++中类的普通成员函数都隐式包含一个指向当前对象的this指针。

3、静态成员函数、成员变量属于类

静态成员函数与普通成员函数的区别

静态成员函数不包含指向具体对象的指针

普通成员函数包含一个指向具体对象的指针

时间: 2024-11-29 09:25:49

C++编译器对属性和方法的处理机制的相关文章

Swift语言中的属性,方法,下标脚本以及继承

从这篇章节起,Swift编程语言指南大部分的重要内容在于概念,代码并不是太多.理解Swift的面向对象理念,语法以及类结构,构造析构过程对于很好的应用Swift语言将会有比较大的帮助. 属性 存储属性 存储属性通常是那些可以通过直接赋值,或者直接访问成员能够获得的属性类型. 它有些要注意的地方: 若一个结构体被声明为常量,则子属性无法被修改了.在Objective-C中,我们总是无法修改结构体的子属性,但是swift却可以,不过这种情况是个例外,当你存储型属性是个结构体并且是个常量,那你就不要再

C# 常量,变量,字段,属性,方法

常量:指在程序编译时已经存在且在程序生命周期内不会发生改变的值,用const定义一个常量. private class TestA     --定义一个类时后边不加() { private const double Pi=3.14; private double GetPi()   --输出pi值得方法,后边带() { double t=pi; return t; } } 变量: 变量本身被用来存储特定类型的数据,可以根据需要随时改变变量中所存储的数据值.变量具有名称.类型和值.变量名是变量在程

Swift的属性,方法,下标脚本以及继承

从这篇章节起,Swift编程语言指南大部分的重要内容在于概念,代码并非太多.理解Swift的面向对象理念,语法以及类结构,构造析构过程对于非常好的应用Swift语言将会有比較大的帮助. 属性 存储属性 存储属性一般是那些可以通过直接赋值,或者直接訪问成员可以获得的属性类型. 它有些要注意的地方: 若一个结构体被声明为常量,则子属性无法被改动了.在Objective-C中,我们总是无法改动结构体的子属性,可是swift却能够,只是这样的情况是个例外,当你存储型属性是个结构体而且是个常量,那你就不要

让IE浏览器支持CSS3圆角属性的方法

如果要想在IE浏览器中实现圆角的效果,我们一般都会采用圆角图片的方式.用图片的话,基本就跟浏览器没有多大关系了,因为任何浏览器都支持这种方式.今天我们主要是讲解如果用CSS3样式表来实现圆角效果,值得注意的是,IE6/7/8这三个IE浏览器版本都不支持CSS3的解析,只有还不太主流的IE9支持CSS3和HTML5的标准.让IE支持CSS3的解析方法有很多种,(HTML5 Shiv – 让该死的IE系列支持HTML5吧)下面介绍一种实用的让IE支持CSS3解析的方法——IE利用VML矢量可标记语言

JavaScript原生对象属性和方法详解——Array对象 转载

length 设置或返回 数组中元素的数目. 注意:设置 length 属性可改变数组的大小.如果设置的值比其当前值小,数组将被截断,其尾部的元素将丢失.如果设置的值比它的当前值大,数组将增大,新的元素被添加到数组的尾部,它们的值为 undefined.所以length不一定代表数组的元素个数. var arr = new Array(3) arr[0] = "John" arr[1] = "Andy" arr[2] = "Wendy" cons

动态创建html内容时所用的W3C DOM属性和方法

document的属性和方法:  document.createElement(tagName) :文档对象上的createElement方法可以创建由tagName指定的元素.如果以串div作为方法参数,就会生成一个div元素.  document.createTextNode(text) :文档对象的createTextNode方法会创建一个包含静态文本text的文本节点.  document.createAttribute(): 用指定的名字创建新的Attr节点.  document.cr

jQuery事件对象的属性和方法

jQuery事件对象的属性和方法 事件对象的属于与方法有很多,但是我们经常用的只有那么几个,这里我主要说下作用与区别 event.type:获取事件的类型 触发元素的事件类型 $("a").click(function(event) { alert(event.type); // "click"事件 }); event.pageX 和 event.pageY:获取鼠标当前相对于页面的坐标 通过这2个属性,可以确定元素在当前页面的坐标值,鼠标相对于文档的左边缘的位置(

JavaScript document属性和方法

JavaScript document属性和方法 --------------------------------------------属性: 1. Attributes     存储节点的属性列表(只读) 2. childNodes     存储节点的子节点列表(只读) 3 .dataType     返回此节点的数据类型 4. Definition     以DTD或XML模式给出的节点的定义(只读) 5. Doctype     指定文档类型节点(只读) 6 .documentEleme

关于JavaScript的对象,属性,方法的一些理解和认识。

对象      万物皆对象,所谓的对象,就是一个实体,一个物体,对象一定是有一个名字的, 在JavaScript中有很多很多对象,这些对象天生就存在在JavaScript中,比如document就是一个对象,window也是对象.     JavaScript想调用一个对象,非常的简单,直接打它的名字即可.     在JavaScript中,每个对象是负责不一样的事情.    document负责一切和文档相关的事情:window负责一切和浏览器窗口相关的事情:console负责一切和控制台相关