IT评测·应用市场-qidao123.com技术社区

标题: 【C++面向对象编程】(二)this指针和静态成员 [打印本页]

作者: tsx81429    时间: 2024-6-14 21:35
标题: 【C++面向对象编程】(二)this指针和静态成员
this指针和静态成员

this指针

C++中类的成员变量和成员函数的存储方式有所差别:

当我们创建一个类的多个对象时,这些对象的成员函数的代码是共享的,也就是说,无论我们创建多少个类的对象,这些函数的代码都只有一份。 但是,每个对象都有自己独立的成员变量。为了在这些共享的成员函数内部引用和修改特定对象的成员变量,C++提供了this指针。this指针是一个隐式的指针,它指向调用非静态成员函数的对象。
示例
  1. #include <iostream>  
  2.   
  3. class MyClass {  
  4. private:  
  5.     int myVar;
  6.   
  7. public:  
  8.     MyClass(int value) : myVar(value) {}
  9.   
  10.     void printMyVar() {  
  11.         std::cout << "The value of myVar for this object is: " << this->myVar << std::endl;  
  12.         // this-> 可以不显式声明,编译器会自动为你处理.this->myVar可以改成myVar
  13.     }  
  14.   
  15.     void setMyVar(int newValue) {  
  16.         this->myVar = newValue;
  17.         // 使用this指针来引用当前对象的myVar
  18.     }  
  19. };  
  20.   
  21. int main() {  
  22.     MyClass obj1(10);
  23.     MyClass obj2(20);
  24.   
  25.     obj1.printMyVar(); // The value of myVar for this object is: 10  
  26.     obj2.printMyVar(); // The value of myVar for this object is: 20  
  27.   
  28.     obj1.setMyVar(30);
  29.     obj1.printMyVar(); // The value of myVar for this object is: 30  
  30.     obj2.printMyVar(); // The value of myVar for this object is: 20,第二个对象的myVar保持不变  
  31.   
  32.     return 0;  
  33. }
复制代码
在这个例子中,MyClass类的两个成员函数:printMyVar和setMyVar都通过this指针来引用和修改当前对象的成员变量。
在类的成员函数内部中,通常不必要显式声明this指针,因为编译器会主动处置惩罚。然而,在某些环境下,可以显式地使用this指针,比方:

示例
  1. #include<iostream>
  2. class MyClass {
  3. private:
  4.     int x;
  5. public:
  6.     MyClass(int value) : x(value) {}
  7.     // 使用this指针来区分成员变量和参数
  8.     void setValue(int x) {
  9.         this->x = x;
  10.     }
  11.     // 使用this指针返回调用对象本身
  12.     MyClass& increment() {
  13.         this->x++;
  14.         return *this; // 返回*this即返回调用对象本身
  15.     }
  16.     int getValue() const {
  17.         return x;
  18.     }
  19. };
  20. int main() {
  21.     MyClass obj(5);
  22.     obj.setValue(20);
  23.     obj.increment().increment(); // 链式调用
  24.     std::cout << obj.getValue() << std::endl; // 输出22
  25.     return 0;
  26. }
复制代码
还可以定义一个MyClass*范例的指针,并将其初始化为this的值,从而在函数内部使用该指针来引用当前对象。这个指针自己不会“更换”this,只是一个额外的指针变量。
示例:
  1. class MyClass{
  2. public:
  3.     int value;
  4.     MyClass(int v) : value(v) {}
  5.     void printValue() {
  6.         MyClass* self = this; // 定义一个MyClass*类型的指针self,并初始化为this
  7.         std::cout << "The value of this object is: " << self->value << std::endl;
  8.         // 现在可以使用self来引用当前对象,就像使用this一样
  9.     }
  10. };
复制代码
这在设计特别的数据布局(如前缀树)时候会用到。但在大多数环境下,简单地使用this就足够了。
静态成员

类的非静态成员(包罗成员变量和成员函数)是类的每个对象所独有的。每一个类的对象会拥有自己独立的内存空间来存储其非静态成员变量的值,并通过this指针来与非静态成员函数举行关联。每个对象在调用非静态成员函数时,都会通过this指针通报自己的地址给该函数,以便函数可以或许访问和修改该对象的成员变量。
类的静态成员(包罗静态成员变量和静态成员函数)在所有类的对象之间是共享的,只存在于一个数据存储区域。静态成员不与类的任何特定对象相关联。因此,静态成员函数内部没有this指针的概念。
静态数据成员: 在类的所有对象之间共享其值。在C++17之前,静态数据成员只能在类外举行初始化。C++17之后可以使用内联关键字inline在类内初始化静态数据成员。
类外初始化静态数据成员:
  1. class MyClass {
  2. public:
  3.     static int count; // 声明静态数据成员
  4.     MyClass() {
  5.         count++;
  6.     }
  7.     ~MyClass() {
  8.         count--;
  9.     }
  10. };
  11. // 在类外初始化静态数据成员
  12. int MyClass::count = 0;
  13. int main() {
  14.     MyClass obj1; // 构造时,count 增加到 1
  15.     MyClass obj2; // 构造时,count 增加到 2
  16.     std::cout << MyClass::count << std::endl; // 输出 2
  17.     return 0;
  18. }
复制代码
使用C++17新增的inline在类内初始化静态数据成员:
  1. #include <iostream>  
  2.   
  3. class MyClass {  
  4. public:  
  5.     // 使用内联变量语法在类内部声明并初始化静态数据成员
  6.     inline static int count = 0;
  7.   
  8.     MyClass() {  
  9.         count++;
  10.     }  
  11.   
  12.     ~MyClass() {  
  13.         count--;
  14.     }  
  15. };  
  16.   
  17. int main() {  
  18.     MyClass obj1; // 构造时,count 增加到 1  
  19.     MyClass obj2; // 构造时,count 增加到 2  
  20.     std::cout << MyClass::count << std::endl; // 输出 2  
  21.     return 0;  
  22. }
复制代码
静态成员函数: 可以通过任何对象的实例或类名来调用,但是不能访问类的非静态成员。
  1. #include <iostream>  
  2. #include <string>  
  3.   
  4. class MyClass {  
  5. private:  
  6.     int nonStaticVar; // 非静态成员变量  
  7.     inline  static int staticVar = 42; // 静态成员变量
  8.   
  9. public:  
  10.     MyClass(int value) : nonStaticVar(value) {}  
  11.   
  12.     // 静态成员函数  
  13.     static void printStaticVar() {  
  14.         std::cout << "The value of staticVar is: " << staticVar << std::endl;  
  15.         // 尝试通过静态成员函数访问非静态成员变量会导致编译错误  
  16.         // std::cout << "The value of staticVar is: " << nonStaticVar << std::endl;  
  17.     }  
  18.       
  19.     // 非静态成员函数  
  20.     void printVars() {  
  21.         std::cout << "The value of staticVar is: " << staticVar << std::endl;  
  22.         std::cout << "The value of nonStaticVar is: " << nonStaticVar << std::endl;  
  23.     }  
  24. };  
  25.   
  26.   
  27. int main() {  
  28.     MyClass obj(10);  
  29.   
  30.     // 通过类名调用静态成员函数  
  31.     MyClass::printStaticVar();   // The value of staticVar is: 42
  32.   
  33.     // 通过对象实例调用静态成员函数
  34.     obj.printStaticVar();  // The value of staticVar is: 42
  35.   
  36.     // 调用非静态成员函数  
  37.     obj.printVars();   
  38.     // The value of staticVar is: 42   
  39.     //The value of nonStaticVar is: 10
  40.     return 0;  
  41. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com技术社区 (https://dis.qidao123.com/) Powered by Discuz! X3.4