c++中类的成员函数调用剖析

此用一个小示例来说明c++中成员函数是怎么调用的

#include <iostream>
using namespace std;

class Test{
public:
	void funcMember(){
		cout << "I‘m member function" << endl;
		int *ptr = reinterpret_cast<int*>(const_cast<Test*>(this));
		//int *ptr = (int*)(const_cast<Test*>(this));
		cout << *ptr << endl; //没弄清为什么在int x; int y;再栈中的部局中间竟有8个字节的cc cc cc cc cc cc cc cc本应x,y紧挨着的
		ptr += 3; //所以就因为多了两个4字节就加了3
		cout << *ptr << endl;
		ptr += 3;
		cout << *ptr << endl;
		ptr += 3;
		cout << *ptr << endl;
		ptr += 3;
		cout << *ptr << endl;
	}
	Test():x(3){}
	int x;
};

int main(){
	Test *t = NULL, *ptr;

	int x = 10;
	int y = 20;
	int z = 30;
	int zz = 40;
	Test tt;
//	t->funcMember();
	ptr = &tt;
	ptr->funcMember();
	cout << "--------------------------" << endl;
	tt.funcMember();

	return 0;
}

先来说明一下,被注释掉的部分,为什么t是空指针,这样的调用还成功呢

请看下图反汇编后的结果

因此第一处画红线的部分,图中漏掉了一

那再看被注释掉后程序的运行结果如何呢?

从结果中可以看出,对象的实例是作为地址传入函数中的,因此只要不使用此地址,无论它是否为空都不会错误,如果使用了向本示例所做的那样,

知道原因也可以灵活改变。

c++中类的成员函数调用剖析

时间: 2024-08-29 18:56:25

c++中类的成员函数调用剖析的相关文章

【c++】Function语义学之成员函数调用方式

非静态成员函数 编译器内部已将member函数实体转换为对等的nonmember函数实体. 转化步骤: 1.改写函数原型以安插一个额外的参数到member function中,使class object可以调用该函数,该额外参数为this指针. 2.将函数中每一个对nonstatic data member的存取操作改为经由this指针来存取 3.对函数名称进行处理,使它在程序中成为独一无二的词汇. 名称的特殊处理 一般而言,member的名称前面会由编译器加上class名称,形成独一无二的命名

使用类作用域操作符进行成员函数调用问题

#include "stdafx.h" #include <iostream> using namespace std; class base { public: int func() { return 100; } private: }; class derived:public base { public: int func() { int tem; tem=base::func(); //这样做是可以的, 显式调用基类中的方法(不然无限递归调用) cout<&l

基类与派生类的指针和成员函数调用原理

基类与派生类的指针和成员函数调用原理 1.如果以一个基础类指针指向一个衍生类对象(派生类对象),那么经由该指针只能访问基础类定义的函数(静态联翩) 2.如果以一个衍生类指针指向一个基础类对象,必须先做强制转型动作(explicit cast),这种做法很危险,也不符合生活习惯,在程序设计上也会给程序员带来困扰.(一般不会这么去定义) 3.如果基础类和衍生类定义了相同名称的成员函数(非虚函数),那么通过对象指针调用成员函数时,到底调用哪个函数要根据指针的类型(基类指针or派生类指针)来确定,而不是

C++语言学习(十四)——C++类成员函数调用分析

C++语言学习(十四)--C++类成员函数调用分析 一.C++成员函数 1.C++成员函数的编译 C++中的函数在编译时会根据命名空间.类.参数签名等信息进行重新命名,形成新的函数名.函数重命名的过程通过一个特殊的Name Mangling(名字编码)算法来实现.Name Mangling算法是一种可逆的算法,既可以通过现有函数名计算出新函数名,也可以通过新函数名逆向推导出原有函数名.Name Mangling算法可以确保新函数名的唯一性,只要命名空间.所属的类.参数签名等有一个不同,那么产生的

C++中类的构造函数调用顺序

当建立一个对象时,首先调用基类的构造函数,然后调用下一个派生类的构造函数,依次类推,直至到达派生类次数最多的派生次数最多的类的构造函数为止.简而言之,对象是由"底层向上"开始构造的.因为,构造函数一开始构造时,总是要调用它的基类的构造函数,然后才开始执行其构造函数体,调用直接基类构造函数时,如果无专门说明,就调用直接基类的默认构造函数.在对象析构时,其顺序正好相反. 下面的这个程序说明这个问题 总结下来,我们必须明确的是当一个类继承与基类,并且自身还包含有其他类的成员对象的时候,构造函

关于虚函数,类的内存分布以及类的成员函数调用原理

1.类的内存分布 空类为了占位,空间占一个字节 成员函数,静态函数,静态变量并不占内存(不和类放在一起) 所有的虚函数也并不和类放在一起,而是将所有的虚函数构造成一个虚函数表,用一个指针指向这个虚函数表,类仅仅存储这个指针,一个指针在32位的机器上占四个字节 所有的非静态成员变量占内存 因此,类的内存分布=所有的非静态成员变量+虚指针(自创的名词:即指向虚函数表的指针) 2.虚函数的原理 一个非继承的类:一个虚指针(指向他的虚函数表). 一个单继承的类:一个虚指针(指向他的虚函数表,这个虚函数表

C# 中类的成员有哪些?

类(class)是C#类型中最基础的类型.类是一个数据结构,将状态(字段)和行为(方法和其他函数成员)组合在一个单元中.类提供了用于动态创建类实例的定义,也就是对象(object).类支持继承(inheritance)和多态(polymorphism),即派生类能够扩展和特殊化基类的机制.使用类声明可以创建新的类.类声明以一个声明头开始,其组成方式如下:先是指定类的特性和修饰符,后跟类的名字,基类(如果有的话)的名字,以及被该类实现的接口名.声明头后面就是类体了,它由一组包含在大括号({})中的

类成员函数调用delete this会发生什么呢?

有如下代码 class myClass { public: myClass(){}; ~myClass(){}; void foo() { delete this; } }; int main() { myClass * aa = new myClass(); aa->foo(); return 0; } 会发生什么呢? 在类的成员函数中能不能调用delete this?答案是肯定的,能调用,而且很多老一点的库都有这种代码.假设这个成员函数名字叫release,而delete this就在这个r

C++并发类成员函数调用(练习1)

一般类成员函数开线程格式 std::thread t1(&类名::函数,&实例化对象,参数....) ||std::thread t1(std::bind(&&类名::函数,&实例化对象,参数....)) 1 #include <iostream> 2 #include <mutex> 3 #include <thread> 4 #include <vector> 5 #include <string> 6