c++类与对象的引入及this指针

目录

struct结构体的扩展和class类的引入

类的对象空间占用

this指针


struct结构体的扩展和class类的引入

c++中的类是c中的结构体的延申和扩展,它兼容了c中结构体的用法,同时struct在c++中也升级成了类。所以在c++中struct可以代替class(不建议这样做),但需要注意的是:struct定义类的时候,成员和方法的默认权限是publicclass的成员和方法的默认权限是private(struct的默认权限为public的原因是c++要兼容c。设想一下,如果struct内的成员变量如class一般默认权限为private,那么站在c的角度上可以看作结构体内的变量外界竟然无法直接访问,这样谈何兼容c)

类的对象空间占用

假设用这样一个类定义对象,对象内存占用怎样计算?函数方法是否要存在每个对象里边?

class student
{
private:
		const char* _name;
		int _age;
		int _cla;
public:
		void studentInit(const char* name, int age, int cla) {
			this->_name = name;
			this->_age = age;
			this->_cla = cla;

		}
		void print() {
			std::cout 
				<< "name:"<<_name 
				<<"\nage:"<<_age 
				<< "\nclass:"<<_cla 
				<< std::endl;
		}
};
	st1.studentInit("zhangsan",10,101);
	std::cout << sizeof(st1) << std::endl;//结果为:12

可以验证对象的空间占用只计算了对象的成员变量,函数并不计入对象的内存空间。而且通过进一步验证,可以知道类与结构体一样具有内存对齐现象。

那么,类内的函数是存在哪里?

结论是:c++中将类内的函数方法存在公共代码区而非对象本身,以此将该函数供该类的所有对象调用。

我们可以验证一下。先使用student类定义多个对象,然后调用不同对象的studentinit()函数,通过反汇编可以发现该函数都在同一个地址空间(02E146Fh)。c++类与对象的引入及this指针_第1张图片

此外,如果一个类内没有成员变量,只有方法,那么它的空间占用为1byte,这块空间实质上不存储任何东西,开辟空间的意义只是占坑,代表这里是一个该类型的对象。简单的验证即可证明

this指针

这里又有另一个问题,所有对象共用一个函数方法,方法如何判断目前是哪一个对象在调用自己?

实际上C++中在调用成员函数的时候,会有隐藏的参数传递

st1.studentInit("zhangsan",10,101);
//上例中的函数调用在编译器看来是以下形式
st1.studentInit(&st1,"zhangsan",10,101);
void studentInit(student* const this,const char* name, int age, int cla) {
			_name = name;
			_age = age;
			_cla = cla;
}

这个参数会将该对象的地址以this指针的形式传给成员方法,在方法内访问对象的成员变量实际上是以this->的方式访问。

             this->_name = name;

             this->_age = age;

             this->_cla = cla;

c++类与对象的引入及this指针_第2张图片

 注意:形参和实参处的隐藏参数是编译器已经规定好的的,不需要写也不能写。

另外,this指针一般情况下是存在栈中 (形参实参都是在栈中)。有些编译器会放在寄存器中,放在ecx中,会更加方便的存取使用

分析下这段代码在(1)、(2)处分别会出现哪些情况?

1.编译错误  2.运行崩溃  3.正常运行

class A {
public:
	void show() {
		cout << "show" << endl;
	}
	void print() {
		cout << _a << endl;
	}
private:
	int _a;
};

int main() {

	A* p = nullptr;
	p->show();//(1)
	p->print();//(2)

	return 0;
}

分析:

p是空指针,调用函数传参后,this指针同样指向该区域,为空指针,同时其成员函数是单独存在公共代码区。

  1. 编译器在编译时无法察觉到空指针或者野指针现象,所以编译不会报错。
  2. 但续过程中,前者在调用存在公共代码区的成员函数时,并未访问this指针中的任何成员,因此前者正常运行。
  3. 后者在调用成员函数时,需要使用this->_a对成员变量进行访问并打印,但this是空指针,使用this->解引用的时候会出现运行崩溃现象

你可能感兴趣的:(c++,开发语言,后端)