目录
  • 静态成员
    • 1.静态成员变量
    • 2.静态成员函数
  • 成员变量和成员函数分开存储
    • this 指针
      • 空指针访问成员函数
        • 总结

          静态成员

          静态成员就是在成员变量和成员函数前加上关键字static,称为静态成员

          静态成员分为:

          1.静态成员变量

           所有对象共享同一份数据
           在编译阶段分配内存
           类内声明,类外初始化
          

          示例:

          #include<iostream>
          using namespace std;
          class Person
          {
          public:
             static int m; // 所有对象共享同一份数据
          };
          int Person::m = 0;// 类内声明,类外初始化
          

          2.静态成员函数

          所有对象共享一个函数
          静态成员函数只能访问静态成员变量
          
          #include<iostream>
          using namespace std;
          class Person
          {
          public:
             static void func()
             {
             	cout << "static void func调用" << endl;
             	m_a = 100;//静态成员函数可以访问静态成员变量
             	//m_b=100,静态成员函数不可以访问非静态成员变量
             	//原因无法区分到底哪个是对象的m_b;
             }
             static int m_a;//静态成员变量
             int m_b;
          };
          int Person::m_a = 0;
          int main()
          {
             //1.通过对象访问
             Person p;
             p.func();
             //2.通过类名访问
             Person::func();
          
             system("pause");
             return 0;
          }
          

          静态成员函数可以访问静态成员变量

          静态成员函数不可以访问非静态成员变量

          私有权限的静态成员函数,也是访问不到的

          成员变量和成员函数分开存储

          在C++中,类内的成员变量和成员函数分开存储

          只有非静态成员变量才属于类的对象上

          空对象:

          #include<iostream>
          using namespace std;
          class Person
          {
          
          };
          void test01()
          {
          	Person p;
          	//空对象占用内存空间为:1
          	//C++编译器会给每个空对象也分配一个字节空间,是为了区分空对象占内存的位置
          	//每个空对象也应该有独一无二的内存地址
          	cout << sizeof(p) << endl;
          }
          int main()
          {
          	test01();
          	return 0;
          }
          

          输出结果:1

          #include<iostream>
          using namespace std;
          class Person
          {
          	int m_a;//非静态成员变量 属于类的对象上
          };
          void test02()
          {
          	Person p;
          	cout << sizeof(p) << endl;
          }
          int main()
          {
          	test02();
          }
          

          输出结果:4

          #include<iostream>
          using namespace std;
          class Person
          {
          	int m_a;//非静态成员变量 属于类的对象上
          	static int m_b; //静态成员变量 不属于类的对象上
          };
          void test02()
          {
          	Person p;
          	cout << sizeof(p) << endl;
          }
          int main()
          {
          	test02();
          }
          

          输出结果:4

          与第二个对比可知:

          静态成员变量 不属于类的对象上

          #include<iostream>
          using namespace std;
          class Person
          {
          	int m_a;//非静态成员变量 属于类的对象上
          	static int m_b; //静态成员变量 不属于类的对象上
          	void func() {}//非静态成员函数 不属于类的对象上
          	static void func2() {} //静态成员函数也不会属于 类的对象上
          };
           int Person::m_b = 0;
          void test02()
          {
          	Person p;
          	cout << sizeof(p) << endl;
          }
          int main()
          {
          	test02();
          }
          

          输出结果:4

          结论:只有非静态成员变量才属于类的对象上

          this 指针

          每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码

          那么问题是:这块代码是如何区分是哪个对象调用自己的呢?

          C++通过提供的特殊的对象指针,this指针,解决上述问题,this 指针指向被调用的成员函数所属的对象,通俗的说,谁调用它,this就指向谁

          this 指针是所有成员函数的隐含参数吗,不需要定义,可直接使用

          this 指针的用途

          1.当形参和成员变量同名时,可用this指针来区分
          2.在类的非静态成员函数中返回对象本身,可用 return  *this 
          

          1.当形参和成员变量同名时,可用this指针来区分

          #include<iostream>
          using namespace std;
          class Person
          {
          public:
          	void func(int age)
          	{
          		this->age = age;  //
          	}
          	int age;
          };
          int main()
          {
          	Person p;
          	p.func(18);
          	cout << p.age << endl;
          	system("pause");
          	return 0;
          }
          

          2.在类的非静态成员函数中返回对象本身,可用 return *this

          #include<iostream>
          using namespace std;
          class Person
          {
          public:
          	Person& func(Person&p)
          	{
          		this->age += p.age;
          		return *this;
          	}
          	int age;
          };
          int main()
          {
          	Person p;
          	p.age = 10;
          	//链式编程思想
          	p.func(p).func(p).func(p);
          	cout << p.age << endl;
          	system("pause");
          	return 0;
          }
          

          空指针访问成员函数

          C++中空指针是可以调用成员函数,但是也要注意有没有用到this指针

          如果用到this指针,需要加以判断保证代码的健壮性

          #include<iostream>
          using namespace std;
          class Person
          {
          public:
          	void ShowPersonclass()
          	{
          		cout << "调用ShowPerclass()函数" << endl;
          	}
          };
          int main()
          {
          	Person* p = NULL;
          	p->ShowPersonclass();
          	system("pause");
          	return 0;
          }
          

          通过空指针p是可以访问到成员函数(不带this指针的成员函数)

          如下代码就是一个错误代码

          #include<iostream>
          using namespace std;
          class Person
          {
          public:
          	void ShowPersonname()
          	{
          		cout << m_name << endl;  //此处出现了this指针
          	}
          	int m_name;
          };
          int main()
          {
          	Person* p = NULL;
          	p->ShowPersonname();
          	system("pause");
          	return 0;
          }
          

          解析:

          此处出现了this指针

          cout << m_name << endl;
          

          相当于

          cout <<this -> m_name << endl;
          

          而this指针是一个空指针,所以会报错

          为了增加代码的健壮性,我们因该做出如下改动

          #include<iostream>
          using namespace std;
          class Person
          {
          public:
          	void ShowPersonname()
          	{
          		if (this == NULL)  //在此判断this是否是空指针
          			return;
          		cout << m_name << endl;
          	}
          	int m_name;
          };
          int main()
          {
          	Person* p = NULL;
          	p->ShowPersonname();
          	system("pause");
          	return 0;
          }
          

          总结

          本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注的更多内容!

          声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。