【C++复习】1、结构体对齐 2、大小端 3、this指针 4、构造函数 5、析构函数

本文详细介绍了C++中的几个核心概念:结构体内存对齐的规则及其原因,大小端存储模式的概念与应用,this指针的作用与特性,以及构造函数和析构函数的功能与使用注意事项。通过理解这些基础知识,能更好地掌握C++编程。
摘要由CSDN通过智能技术生成

为什么存在结构体内存对齐
1.平台原因
不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出异常。
2.性能原因
数据结构尤其是(尤其是栈)应该尽可能的在自然边界上对齐。
原因在于,为了访问未对齐的内存,处理器需要做两次内存访问;而对齐的内存仅需要一次内存访问。

1、结构体内存对齐规则

1.第一个成员在与结构体偏移量为0的地址处。
2.其它成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
注意:对齐数=编译器默认的一个对齐数与该成员大小的较小值。
VS中默认的对齐数为8.
3.结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
4.如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

#12
struct s1
{
	char c1;
	int i;
	char c2;
};
#8
struct s2
{
	char c1;
	char c2;
	int i;
};
#16
struct s3
{
	double d;
	char c;
	int i;
};
#32
struct s4
{
	char c1;
	struct s3 S3;
	double d;
};

总结:结构体的内存对齐是拿空间来换取时间的做法。设计结构体的时候,既要满足对齐,又要节省空间,只需让占用内存小的成员尽量集中在一起。pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

2、大小端

什么是大小端
大端(存储)模式:是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中。
小端(存储)模式:是指数据的低位保存在内存的低地址中,而数据的高位,保存在内存的高地址中。
为什么会有大端和小端
这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8个bit。而在C语言中除了8bit的char之外,还有16bit的short型,32 bit的long型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器大于一个字节,那么必然存在如何将多个字节安排的问题。因此就导致了大端和小端存储模式。
百度2015年系统工程师笔试题
请简述大端字节序和小端字节序的概念,设计一个小程序来判断当前机器的字节序。`
解题思路:指针类型转换,最后取char*指针的值,判断int低地址的数据是否为1。

#include<iostream>
using namespace std;
int check_sys()
{
	int i = 1;
	return (*(char *)&i);
}
int main()
{
	int ret= check_sys();
	if (ret == 1)
	{
		cout << "小端" << endl;
	}
	else
	{
		cout << "大端" << endl;
	}
	return 0;
}

3、this指针

先看一段代码

#include<iostream>
using namespace std;
class student
{
public:
	void display()
	{
		cout << age << endl;
	}
	void setAge(int age)
	{
		age = age;
		cout << age << endl;
	}
private:
	int age;
};
int main()
{
	student s;
	s.setAge(17);
	s.display();
	return 0;
}

代码输出:
17
-858993460
我们可以看到s对象display()的输出是随机值。原因是student类没有对成员变量age和setAge()方法中的age作区分,而display()方法传递的是成员变量中未初始化的age,所以随机值。
为了解决该问题,只需使用this指针对age进行区分即可。

#include<iostream>
using namespace std;
class student
{
public:
	void display()
	{
		cout << age << endl;
	}
	void setAge(int age)
	{
		this->age = age;
		cout << age << endl;
	}
private:
	int age;
};
int main()
{
	student s;
	s.setAge(17);
	s.display();
	return 0;
}

代码输出:
17
17
接下来详细了解this指针
什么是this指针
C++编译器给每个“非静态的成员函数”增加了一个隐藏的指针参数,让该指针指向当前的对象(函数运行时调用该函数的对象),在函数体中所有的成员变量的操作,都是通过该指针取访问。只不过所有操作对用户是透明的,即用户不需要来传递,编译器自动完成。
this指针的特性
1.this指针的类型:类类型* const
2.只能在成员函数内部使用
3.this指针本质其实是一个成员函数的形参,当对象调用成员函数时,将对象地址作为实参传递给this形参,所以对象中不存储this指针
4.this指针是成员函数第一个隐含的指针形参,一般情况下由编译器通过ecx寄存器自动传递,不需要用户传递

4、构造函数

什么是构造函数
构造函数是类中特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,保证每个数据成员都有一个合适的初始值,并且在对象的声明周期内只调用一次。
构造函数的特征
1.函数与类名相同
2.无返回值
3.对象实例化时编译器调用对应的构造函数
4.构造函数可以重载
5.如果没有显示定义构造函数,则C++编译器会自动生成一个无参的构造函数,一旦用户显示定义编译器将不再生成
6.无参构造函数(可以为编译器默认生成)和全缺省构造函数都称为默认构造函数,并且默认构造函数只能有一个
7.C++把数据类型分为内置数据类型和自定义数据类型。内置类型就是语法已经定义好的类型:如int,char等。自定义类型就是我们使用struct,class等自己定义的类型。我们不写,编译器默认生成的构造函数,对于内置类型不做初始化处理,对于自定义类型编译器会调用它的默认构造函数。因此编译器默认生成的构造函数是有用的
初始化列表
以一个冒号开始,接着是以逗号分隔的数据成员列表,每个“成员变量”后边跟着一个放到花括号中的初始值或者表达式。

class Date
{
public:
	Date(int year, int month, int day)
		:_year(year)
		,_month(month)
		,_day(day)
	{}
	
private:
	int _year;
	int _month;
	int _day;
};

注意
每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)
类中包含以下成员,必须放在初始化列表位置进行初始化
引用成员变量
const成员变量
自定义类型成员(该类没有默认构造函数)
尽量使用初始化列表初始化,因为不管是否使用初始化列表,对于自定义类型成员变量,一定会先试用初始化列表初始化
成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关

5、析构函数

什么是析构函数
与构造函数功能相反,析构函数不是完成对象的销毁,局部对象销毁工作是由编译器完成的。而在对象销毁时会自动调用析构函数,完成类的一些资源清理工作。
析构函数的特性
1.析构函数是在类名前边加入~
2.无参数无返回值
3.一个类有且只有一个析构函数。若未显示定义,系统会自动生成默认的析构函数
4.对象生命周期结束时,C++编译器会自动调用析构函数
5.对于编译器自动生成的析构函数,对内置数据类型不做处理,会对自定义数据类型成员调用它的析构函数

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值