C++学习日记---第16天

笔记复习

1.C++对象模型

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

我们知道,C++中的成员变量和成员函数均可分为两种,一种是普通的,一种是静态的,对于静态成员变量和静态成员函数,我们知道他们不属于类的对象,事实上,非静态成员函数也即普通的成员函数也不属于类的对象。只有非静态成员变量也即普通的成员变量才属于类的对象。

下面是代码示例的完整代码:

cpp 复制代码
#include<iostream>
using namespace std;

class person {
	int m_A;
	static int m_B;
	void func() {
	}
	static void func1() {}
};

void test01() {
	person p;
	cout << "size of p=" << sizeof(p) << endl;
}

void test02() {
	person p;
	cout << "size of p=" << sizeof(p) << endl;
}

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

在C++中,空对象的内存空间为一个字节,这是由C++编译器分配的,目的是为了区分空对象占内存的位置,这样每个对象都会有独一无二的内存地址,当我们删除person类中的代码运行程序后将会输出两个1

cpp 复制代码
#include<iostream>
using namespace std;

class person {
};

void test01() {
	person p;
	cout << "size of p=" << sizeof(p) << endl;
}

void test02() {
	person p;
	cout << "size of p=" << sizeof(p) << endl;
}

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

前面我们讲到只有成员变量才属于C++的对象,因此我们在空类的基础上写入成员函数,静态成员变量,静态成员函数,这个类的对象也依旧是空对象

cpp 复制代码
#include<iostream>
using namespace std;

class person {
    static int m_B;
    void func() {
}
    static void func1() {}
};

void test01() {
	person p;
	cout << "size of p=" << sizeof(p) << endl;
}

void test02() {
	person p;
	cout << "size of p=" << sizeof(p) << endl;
}

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

2.this指针

我们知道,当我们创建并调用类的对象时,这些对象会共用类中的成员函数,那么这些函数如何区分时哪个对象调用自己呢?这时候就有了this指针,C++通过提供this指针来解决该问题,。

this指针是一种特殊的指针,this指针指向被调用成员函数的所属的对象(this指向整个对象,而不只是对象里面的成员 )。在非静态成员函数内部,你可以使用 this 指针访问调用对象的成员。this 实际上是当前类类型的指针,例如,对于类Kunkun的成员函数,this 是 Kunkun 类型的指针。

作用:

1)解决变量命名冲突

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

(this指针还有更多用途,但过于复杂,这里不再介绍)

1)解决变量命名冲突

cpp 复制代码
#include<iostream>
using namespace std;

class person {
public:
	person(int age) {
		age = age;
	}
	int age;
};

void test01() {
	person p1(18);
	p1.age = 18;
}

int main() {
	test01();


	return 0;
}

在这份代码种,person有参函数中的age是赋值给形参,即形参赋值给形参,并没有将接收到的形参的值赋值给成员变量,因此成员变量未初始化,当我们运行这个代码的时候就会出现成员变量未初始化的问题,这时候我们需要使用this指针

cpp 复制代码
#include<iostream>
using namespace std;

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

void test01() {
	person p1(18);
	p1.age = 18;
}

int main() {
	test01();


	return 0;
}

这里this指针指向被调用函数(person有参函数)所属对象(p1)的成员变量age,这样就把age区分开了,不过在实际的编程中我们会规范化命名尽量避免这种情况出现。

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

cpp 复制代码
#include<iostream>
using namespace std;

class person {
public:
	person(int age) {
		this->age = age;
	}
	person& personaddage(person &p) {
		this->age += p.age;//将自身的年龄加上传入对象的年龄
		return *this;
        //this返回的是person类型的对象,因此函数要设置为person类型,&允许函数返回一个对象的引用而不是一个新的对象,返回对象的引用允许多个函数连续调用操作同一个对象
	}
	int age;
};

void test02() {
	person p1(10);
	person p2(10);
    //链式调用:
	p2.personaddage(p1).personaddage(p1).personaddage(p1);
    //p2是对象,因此p2.personaddage(p1)语法正确,而如果没有return *this;
    //那么返回的数据类型就是int类型,int.personaddage(p1)不成立,因此需要返回对象
	cout << p2.age << endl;
}

int main() {
	test02();

	return 0;
}

细心的小伙伴可以发现,this指针指向一个值的时候我们修改了这个值,那么this指针能否修改指针的指向呢?答案是不能,因此this指针实际上是指针常量(指针指向的值可以改变,但指针的指向无法改变)

3.空指针访问成员函数

C++中空指针也可以访问成员函数

  1. 若成员函数中未使用到成员变量,可使用空指针调用该成员函数;

  2. 若成员函数中使用了成员变量,须对this进行判空操作,以防止程序崩溃。

对于第2点,也即C++无法用空指针来调用成员函数的成员变量

cpp 复制代码
#include<iostream>
using namespace std;

class person {
public:
	void showclassname() {
		cout << "this is person class" << endl;
	}
	void showpersonage() {
		if (this == NULL) {
        //没有判空操作时程序会报错
			return;
		}
		cout << "age=" << this->m_age << endl;//this指针指向p,p是一个空指针,是无法访问属性的
	}
	int m_age;
};

void test01() {
	person* p = NULL;
	p->showclassname();
	p->showpersonage();
}

int main() {
	test01();


	system("pause");
	return 0;
}
相关推荐
yijianace5 分钟前
Python线程与多线程完全总结(从入门到理解并发本质)
开发语言·python
不知名的老吴13 分钟前
线程的生命周期之线程同步
java·开发语言·jvm
为何创造硅基生物14 分钟前
独占指针的创建std::make_unique 本身自带堆出现
c++
kyle~25 分钟前
ROS 2 与 Isaac Sim 联合仿真(一)体系架构、环境选型与基础通信闭环
c++·机器人·nvidia·仿真·ros2
努力努力再努力wz1 小时前
【内存管理与高并发内存池系列】从 mmap 到 malloc:文件映射、匿名映射与 glibc 内存分配机制详解
linux·c语言·数据结构·数据库·c++·qt·链表
J2虾虾1 小时前
C 语言 void 完全用法
c语言·开发语言
八解毒剂1 小时前
数据结构-平衡二叉树——对二叉搜索树的优化
数据结构·c++·算法
sensen_kiss1 小时前
CPT304 SoftwareEngineeringII 软件工程 2 Pt.9 软件测试 (Software Testing)(下)
学习·软件工程
会Tk矩阵群控的小木1 小时前
基于Python的iMessage短信群发与社媒多账号统一管理系统实现
开发语言·windows·python·新媒体运营·开源软件·个人开发
我是一颗柠檬1 小时前
【Java项目技术亮点】分库分表+数据路由策略:单表5000万后的架构升级方案
java·开发语言·分布式·架构