学习:类和对象——对象模型和this指针

成员变量和成员函数分开存储:

在C++中,类内的成员变量和成员函数分开存储

第一点:空对象占用内存空间1个字节
第二点:只有非静态成员变量才属于类的对象上,非静态成员函数静态成员函数静态成员变量不属于类的对象上

示例代码如下:结果为4个字节

#include<iostream>
#include<string>

using namespace std;

class Person { // 空对象占一个字节
public:
	int m_a; // 非静态成员变量 属于类的对象 打印内存空间为四个字节
	
	static int m_b; // 静态成员变量 不属于类的对象
	
	void func() {}// 非静态成员函数 不属于类的对象

	static void s_func() {}// 静态成员函数 不属于类的对象
};
int Person::m_b = 1;

void test01() {
	Person p;
	cout << sizeof(p) << endl;
}

int main() {
	test01();
	system("pause");
	return 0;
}

this指针概念:

this指针指向被调用的成员函数所属的对象

特点1:this指针是隐含每一个非静态成员函数内的一种指针

特点2:this指针不需要定义,直接使用即可

this指针的用途:

1、当形参和成员变量同名时,可用this指针来区分
2、在类的非静态成员函数中返回对象本身,可使用return *this

示例:

①所指的代码这种输出的数据是错误的,原因就是形参和成员变量同名,编译器就不知道age=age 到底是生成了一个age给age赋值,还是给自身的对象age赋形参的值,所以我们可以通过this指针来解决问题,this指针指向被调用的成员所属的对象

#include<iostream>
#include<string>

using namespace std;

class Person{
public:
	Person(int age) {
		//age = age; ①这段错误
                this->age = age;
	}

public:
	int age;
};

void test01() {
	Person p1(18);
	cout << p1.age << endl;
}

int main() {
	test01();
	system("pause");
	return 0;
}

第二点:在类的非静态成员函数中返回对象本身,可使用return *this

示例

#include<iostream>
#include<string>

using namespace std;

class Person{
public:
	Person(int age) {
		this->age = age;
	}

	Person & addage() {
		this->age += 10;
		//this指针指向被调用的成员函数所属的对象,那么this指针保存的就是p1的内存地址,那么我们返回*this,那么返回的就是本身p1的本体
		return *this;
	}

public:
	int age;
};

void test01() {
	Person p1(18);
	p1.addage().addage().addage(); // p1.addage()之后本身p1的本体然后继续addage那么就继续+10了
	cout << p1.age << endl;
}

int main() {
	test01();
	system("pause");
	return 0;
}

拓展:听老师说如果把 Person类中定义的Person & addage()&去掉的话,那么结果会是什么呢?

结果:输出28,那么只加了一次,那么后面的addage都去哪了呢?

答案:当Person addage() 方式是以值传递的方式返回对象,那么就会进行拷贝构造函数,复制一个新的对象返回

记住一点:当&修饰的时候,返回的是本体,当&没用修饰的时候 返回一个新的对象


空指针访问成员函数

C++中空指针也是可以调用成员函数的,但是也要注意有没有用到this指针

为什么空指针可以调用成员函数呢?个人理解:根据上文联系理解,成员变量和成员函数是分开的,只有非静态成员变量是对象本身的

#include<iostream>
#include<string>

using namespace std;

class Person {

public:
	
	void print_age() {
		
		if (this == NULL) { //如果用到this指针,需要加以判断保证代码的健壮性
			return;
		}
		
		cout << this->m_age << endl;
	}

	void print_hello() {
		cout << "hello world" << endl;
	}

public:
	int m_age;
};

void test01() {
	Person * p = NULL;
	p->print_hello();
	p->print_age(); //无法访问


}

int main() {
	test01();
	
	system("pause");
	return 0;
}

const修饰成员函数:

常函数:

1、成员函数后加const后我们称为这个函数为常函数
2、常函数内不可以修改成员属性
3、成员属性声明时加关键字mutable后,在常函数中依然可以修改

常对象:

1、声明对象前加const称该对象为常对象
2、常对象只能调用常函数

示例代码:

#include<iostream>
#include<string>

using namespace std;

class Person{
public:
	Person() {
		this->a = 1;
		this->b = 2;
	
	}

	void showP() const { //此时如果我们加了const 那么这个showP函数 也成为常函数  原本this是指针常量 ,那么加了const之后也就是const Person * const this ,不能修改地址也不能该能值
		//this指针的本质是 指针常量 也就是 Person * const p 
		//this->a = NULL; //无法运行 因为此时的this是const Person * const this 无法修改指向
		this->b = 100; //可以运行,因为b为mutable修饰
		cout << b << endl;

	}

public:
	int a;
	mutable int b; //mutable 修饰为可修改 可变的

};


int main() {
	Person p;
	p.showP();
	

	
	system("pause");
	return 0;
}
原文地址:https://www.cnblogs.com/zpchcbd/p/11864316.html