失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > C++ 笔记(18)— 类和对象(this 指针 指向类的指针 类静态成员变量和函数)

C++ 笔记(18)— 类和对象(this 指针 指向类的指针 类静态成员变量和函数)

时间:2022-11-25 21:42:17

相关推荐

C++ 笔记(18)— 类和对象(this 指针 指向类的指针 类静态成员变量和函数)

1. this 指针

C++中,每一个对象都能通过this指针来访问自己的地址。this指针是所有成员函数的隐含参数。因此,在成员函数内部,它可以用来指向调用对象。

友元函数没有this指针,因为友元不是类的成员。只有成员函数才有this指针。

在类中,关键字this包含当前对象的地址,换句话说,其值为&object。当您在类成员方法中调用其他成员方法时,编译器将隐式地传递this指针—函数调用中不可见的参数:

class Human{private:void Talk(string msg){cout << msg << endl;}public:void IntroduceSelf(){Talk("hello world"); // Talk(this, "hello world")}}

方法IntroduceSelf()使用私有成员Talk()在屏幕上显示一句话。实际上,编译器将在调用Talk时嵌入this指针,即Talk(this, "hello world")

从编程的角度看,this的用途不多,且大多数情况下都是可选的。见下:

void SetAge(int humansAge){this->age = humansAge; // same as age = humansAge}

调用静态方法时,不会隐式地传递this指针,因为静态函数不与类实例相关联,而由所有实例共享。要在静态函数中使用实例变量,应显式地声明一个形参,并将实参设置为this指针。

因为this的目的总是指向“这个”对象,所以this是一个常量指针,我们不允许改变this中保存的地址。

2. 指向类的指针

一个指向C++类的指针与指向结构的指针类似,访问指向类的指针的成员,需要使用成员访问运算符->,就像访问指向结构的指针一样。与所有的指针一样,您必须在使用指针之前,对指针进行初始化。

#include <iostream>#include <string>using namespace std;class Box{public:// 构造函数声明Box(double, double, double);double Volume();private:double length;// Length of a boxdouble breadth; // Breadth of a boxdouble height;// Height of a box};Box::Box(double l=2.0, double b=2.0, double h=2.0){cout <<"Constructor called." << endl;length = l;breadth = b;height = h;}double Box::Volume(){return length * breadth * height;}int main(void){Box Box1(3.3, 1.2, 1.5); // Declare box1Box Box2(8.5, 6.0, 2.0); // Declare box2Box *ptrBox;// Declare pointer to a class.// 保存第一个对象的地址ptrBox = &Box1;// 现在尝试使用成员访问运算符来访问成员cout << "Volume of Box1: " << ptrBox->Volume() << endl;// 保存第二个对象的地址ptrBox = &Box2;// 现在尝试使用成员访问运算符来访问成员cout << "Volume of Box2: " << ptrBox->Volume() << endl;return 0;}

3. 类静态成员

可以使用static关键字来把类成员定义为静态的。当我们声明类的成员为静态时,这意味着无论创建多少个类的对象,静态成员都只有一个副本。

静态成员在类的所有对象中是共享的。如果不存在其他的初始化语句,在创建第一个对象时,所有的静态数据都会被初始化为零。

我们不能把静态成员的初始化放置在类的定义中,但是可以在类的外部通过使用范围解析运算符::来重新声明静态变量从而对它进行初始化,如下面的实例所示。

3.1 静态成员变量

静态成员数据也可以分为共有的(Public)和私有的(Private),静态成员数据的声明方法为:

static data_type data_name;

由于静态成员数据不是仅仅属于某一个具体对象的,所以它不能再构造函数中被初始化。否则岂不是每创建一个对象,静态成员数据都要被初始化一次?

如果类的头文件会被直接或间接地重复包含,则静态成员数据也会被重复初始化。为了避免这个问题,我们可以将类的声明和定义分离。

如果类的头文件绝对不会被重复包含,那么把静态成员数据的初始化放在类的头文件中也是勉强可以接受的。

静态成员数据的初始化语句为:

数据类型 类名::静态成员数据=初始值;

静态成员数据是某一个类所具有的属性,而不是某一个对象的属性,所以它的存在并不依赖于对象。

示例代码:

#include <iostream>#include <string>using namespace std;class Box{public:Box(double, double, double); // 构造函数声明double Volume();static int objectCount;private:double length;// Length of a boxdouble breadth; // Breadth of a boxdouble height;// Height of a box};// 初始化类 Box 的静态成员int Box::objectCount = 0;Box::Box(double l=2.0, double b=2.0, double h=2.0){cout <<"Constructor called." << endl;length = l;breadth = b;height = h;objectCount++; // 每次创建对象时增加 1}double Box::Volume(){return length * breadth * height;}int main(void){Box Box1(3.3, 1.2, 1.5); // 声明 box1Box Box2(8.5, 6.0, 2.0); // 声明 box2// 输出对象的总数// Total objects: 2cout << "Total objects: " << Box::objectCount << endl;return 0;}

3.2 静态成员函数

既然成员数据可以属于某一个类而不属于某一个具体的对象,那么成员函数也可以这样。在C++中静态成员函数也是属于某一个类而不属于某一个具体的对象的。

静态成员函数的声明方法为:

static 返回值类型 函数名(参数表);

不过在定义静态成员函数时,却不能出现static

如果把函数成员声明为静态的,就可以把函数与类的任何特定对象独立开来。静态成员函数即使在类对象不存在的情况下也能被调用,静态函数只要使用类名加范围解析运算符::就可以访问。

由于静态成员函数是属于类的,不是属于某一个具体的对象,所以它分不清楚到底是哪个对象的非静态成员数据,故而不能访问非静态成员数据。

所以静态成员函数只能访问静态成员变量数据、其他静态成员函数和类外部的其他函数。

静态成员函数有一个类范围,他们不能访问类的this指针。您可以使用静态成员函数来判断类的某些对象是否已被创建。

静态成员函数与普通成员函数的区别:

静态成员函数没有this指针,只能访问静态成员(包括静态成员变量和静态成员函数)。普通成员函数有this指针,可以访问类中的任意成员;而静态成员函数没有this指针。

#include <iostream>#include <string>using namespace std;class Box{public:Box(double, double, double); // 构造函数声明double Volume();static int objectCount;static int getCount();private:double length;// Length of a boxdouble breadth; // Breadth of a boxdouble height;// Height of a box};// 初始化类 Box 的静态成员int Box::objectCount = 0;// 在定义静态成员函数时,却不能出现 `static`int Box::getCount(){return objectCount;}Box::Box(double l=2.0, double b=2.0, double h=2.0){cout <<"Constructor called." << endl;length = l;breadth = b;height = h;objectCount++; // 每次创建对象时增加 1}double Box::Volume(){return length * breadth * height;}int main(void){// 在创建对象之前输出对象的总数cout << "Inital Stage Count: " << Box::getCount() << endl;Box Box1(3.3, 1.2, 1.5); // 声明 box1Box Box2(8.5, 6.0, 2.0); // 声明 box2// 在创建对象之后输出对象的总数cout << "Final Stage Count: " << Box2.getCount() << endl;return 0;}

其中Box2.getCount()等价于Box::getCount()。即类型::静态成员函数(参数列表)等价于对象名.静态成员函数(参数列表),但更推荐前者,比较符合静态成员函数定义。

输出结果:

Inital Stage Count: 0Constructor called.Constructor called.Final Stage Count: 2

类中特殊成员变量的初始化问题:

常量变量:必须通过构造函数参数列表进行初始化。引用变量:必须通过构造函数参数列表进行初始化。普通静态变量:要在类外通过"::"初始化。静态整型常量:可以直接在定义的时候初始化。静态非整型常量:不能直接在定义的时候初始化。要在类外通过"::"初始化。

如果觉得《C++ 笔记(18)— 类和对象(this 指针 指向类的指针 类静态成员变量和函数)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。