类和命名空间一样都是定义一个独立的域,在C++中,有四个域,分别是“局部域”、“全局域”、“命名空间域”、“类域”。每个域的内容互不干扰,用“::”来访问。
一、类的定义
类用关键字“class”定义,一般定义类的格式如下:
class Test
{
};
可以看到,类和C语言的结构体相似(虽然在C++中,结构体也可以定义类)但是他们又有所不同。
1.类里面可以定义或者声明函数。
2.类有访问限定符(public、private、protected)用来限制类域内容的访问权限。
3.在类中定义的函数默认内联。
1、类的成员
类域中可以定义许多函数或者声明变量变量例如:
class Test
{
int Add(int a, int b)
{
return a + b;
}
int a;
char b;
double c;
//......
};
或者
class Test
{
int Add(int a, int b);
int a;
char b;
double c;
//......
};
int Test::Add(int a, int b)
{
return a + b;
}
2、类的访问限定符(public、private、protected)
在这里介绍public、private,即“公共的”、“私有的”。
如果不加访问限定符,那么类域中的内容默认是私有的,那么外界是不可访问的,但是类的成员是可以访问类域中的内容的。如果想要在外界访问,那么可以使用访问限定符“public”,另外,访问限定符作用的范围是该访问限定符到下一个访问限定符之间或者直到遇到类域的结尾“}”,例如:
class Test
{
public:
int Add(int a, int b);
int a;
char b;
double c;
//......
};
int Test::Add(int a, int b)
{
return a + b;
}
这里表示“public”以下的内容是可以被外界访问到的。
示例(代码补全):
class Test
{
public:
int Add(int a, int b);
private:
int a;
char b;
double c;
//......
};
这里表示“public”到“private”之间的内容是可以被外界访问到的,“private”往后的内容外界访问不到。
示例(代码补全):
当要使用类域里的参数时,必须指定是哪个类域。
二、对象的实例化
通过类在内存中创建对象的过程叫做类实例化对象。
类是对象的抽象描述,当我们定义类的过程,可以看做是在画一份图纸,而通过类实例化对象的过程可以看做是按照图纸搭建建筑。因此一个类可以实例化出来很多对象。且类是不占据空间,只有通过类实例化出的对象才会在内存中开辟空间。
通过类实例化对象的操作和结构体类似:
class Test
{
public:
int Add(int a, int b);
private:
int a;
char b;
double c;
//......
};
int Test::Add(int a, int b)
{
return a + b;
}
Test Mytest1;
Test Mytest2;
Test Mytest3;
Test Mytest4;
//......
每个对象都是独立的个体,互补干扰。
三、对象的大小
在类实例化出的对象中,对象的大小遵循结构体的内存对齐规则。且对象只包含变量的大小,不包含函数的大小(函数储存在其他公共的地方,因此当一个对象的指针指向nullptr的时候,对它进行访问成员函数是不会造成程序崩溃的(前提是成员函数里面没有成员变量))。如果类中什么都不定义,那么它实例化出的对象的大小是一个字节(代表这个类是存在的)。
四、this指针
先看以下示例:
#include <iostream>
class Test
{
public:
void init(int x, int y)
{
a = x;
b = y;
}
void test()
{
std::cout << a + b << std::endl;
}
private:
int a;
int b;
//......
};
Test Mytest1;
Test Mytest2;
//......
int main()
{
Mytest1.init(1,2);
Mytest2.init(0,0);
Mytest1.test();
Mytest2.test();
return 0;
}
运行结果:
在以上代码中,编译器是如何知道在调用test的时候,用的是哪一个对象呢?
实际上,在程序编译之后,会在每一个成员函数的第一个参数之前加上一个“类名* const this”的指针,这里称作“this指针”。函数在调用的时候也会自动把对象的地址传入函数。函数里面对对象成员变量的操作等同于对“this->成员变量”的操作,这是隐式操作,开发者也可以在函数中显示的使用this指针。但值得之一的是,开发者不能在函数形参中显示的定义this指针,这种行为会引起编译器的报错。