计算机硬件有两种储存数据的方式:大端字节序(big endian)和小端字节序(little endian)。
我们现在有一个整数是258。用16进制表示是0x0102,然后我们把这个整数拆分成两个字节,第一个字节为 0000 0001,第二个字节为 0000 0010。
如果在一个使用大端字节序的电脑上,这个整数会被这样存放:
如果一个使用小端字节序的电脑上,这个整数的高字节就会存放在高地址上:
现在大部分的机器,都采用了小端字节序。但是在 IO 方面,则大部分使用大端字节序。例如,你要使用网络发送一个 int 类型的变量,要先把 int 转换成大端字节序,然后通过网络发送。
大端字节序又被称之为网络细节序。
判断电脑是大端字节序还是小端字节序?
#include
int main()
{
int i = 0x1122;
char * p = (char *)&i;
if (p[0] == 0x22 && p[1] == 0x11) {
printf("Little Endian\n");
}
else if (p[0] == 0x11 && p[1] == 0x22) {
printf("Big Endian\n");
}
}
int JudgeSystem(void) {
int a = 1;
char * p = (char *)&a;
if (1 == *p) {
return 1;
} else {
return 0;
}
}
构造函数
#include
class Staff
{
public:
Staff();
};
可以看到,这里定义了一个名称和类名相同,没有返回值的函数,这个函数称为构造函数。构造函数的特殊之处在于,他会在类实例化的时候被调用。
我们先实现一下这个函数,在函数中打印一行:
#include "Staff.hpp"
#include
Staff::Staff()
{
printf("构造函数被调用\n");
}
然后在 main 中调用一下:
#include
#include "Staff.hpp"
int main(int argc,char **argv)
{
Staff staff1;
return 0;
}
运行的时候,可以看到,刚刚的那条打印语句被运行了。
此外,构造函数是可以有参数的,我们常常用构造函数来进行初始化。例如,我们可以利用构造函数对 name 和 age 进行传值。
Staff.hpp
#include
class Staff
{
public:
Staff(std::string _name, int _age);
public:
std::string name;
int age;
};
Staff.cpp
#include "Staff.hpp"
#include
Staff::Staff(std::string _name, int _age)
{
name = _name;
age = _age;
}
当然,对于有参数的构造函数,调用的时候只要传进去参数就行了。现在,我们可以创建一个名叫 “mooc”,29 岁的员工了。
#include
#include "Staff.hpp"
int main(int argc,char **argv)
{
Staff staff("mooc", 29);
return 0;
}
析构函数
对象实例化的时候,会调用构造函数,而对象销毁的时候,就会调用析构函数。我们先来尝试写一个析构函数:
Staff.hpp
#include
class Staff
{
public:
Staff(std::string _name, int _age);
~Staff();
public:
std::string name;
int age;
};
Staff.cpp
#include "Staff.hpp"
#include
Staff::Staff(std::string _name, int _age)
{
name = _name;
age = _age;
printf("构造函数被调用\n");
}
Staff::~Staff()
{
printf("析构函数被调用\n");
}
调用代码不改,然后再运行一下。我们发现,程序在调用了构造函数之后,又调用了析构函数。
我们之前讲过栈内存,这个对象是分配在栈上面的,实例化的时候,调用了构造函数,而紧接着,main 函数就要结束了,这个栈对象就自动销毁了,销毁的时候,就调用了析构函数。