zoukankan      html  css  js  c++  java
  • 静态属性和静态方法2

    潜规则:

    • 静态成员是所有对象共享的,所以不能在静态方法里访问非静态的元素。
    • 非静态方法可以访问类的静态成员,也可以访问类的非静态成员。

    为什么呢?

      回顾下:this指针是类的一个自动生成、自动隐藏的私有成员,它存在于类的非静态成员函数中,指向被调用函数所在的对象的地址。当一个对象被创建时,该对象的 this指针就自动指向对象数据的首地址。我们从一个比较有特色的例子来体会 this指针的工作原理:特色例子.txt。

    #include<iostream>
    
    class Point
    {
    private:
      int x, y;
    public:
      Point(int a, int b)
    	{ 
    		x = a;
    		y = b;
    	}
      void MovePoint( int a, int b)
    	{ 
    		x = a; 
    		y = b;
    	}
      void print()
    	{ 
    		std::cout << "x=" << x << "y=" << y << endl;
    	}
    };
    
    int main()
    {
      Point point1(10, 10);
      point1.MovePoint(2, 2);
      point1.print();
    
    	return 0;
    }
    
    // 当对象point1调用MovePoint(2,2)函数时,即将point1对象的地址传递给了this指针。
    
    // MovePoint函数的原型事实上应该是 void MovePoint( Point *this, int a, int b);
    // 第一个参数是指向该类对象的一个指针,我们在定义成员函数时没看见是因为这个参数在类中是隐含的。
    
    // 这样point1的地址传递给了this,所以在MovePoint函数中便可以显式的写成:void MovePoint(int a, int b) { this->x = a; this->y = b;} 
    // 即可以知道,point1调用该函数后,也就是point1的数据成员被调用并更新了值。

      在任何一个方法里都可以使用 this 指针。从本质上讲,C++中的对象其实是一种特殊的结构 -- 除了变量,还包含着一些函数的特殊结构。 在程序运行时,对象的属性(变量)和方法(函数)都是保存在内存里,这就意味着它们各自都有与之相关联的地址。 这些地址都可以通过指针来访问,而 this指针毋庸置疑是保存着对象本身的地址。

      每当我们调用一个方法的时候,this指针都会随着你提供的输入参数被秘密的传递给那个方法。 正是因为如此,我们才能在方法里像使用一个局部变量那样使用 this指针。 因为静态方法不是属于某个特定的对象,而是由全体对象共享的,这就意味着它们无法访问 this指针。所以,我们才无法在静态方法里访问非静态的类成员。

    另外需要注意:

    • 在使用静态属性的时候,千万不要忘记为它们分配内存。具体做法很简单,只要在类声明的外部对静态属性做出声明(就像声明一个变量那样)即可。
      #include <iostream>
      #include <string>
      
      class Pet
      {
      public:
          Pet(std::string theName);
          ~Pet();
      
          static int getCount();
      
      protected:
          std::string name;
      
      private:
          static int count;//声明了count静态属性 
      };
      
      class Dog : public Pet
      {
      public:
          Dog(std::string theName);
      };
      
      class Cat : public Pet
      {
      public:
          Cat(std::string theName);
      };
      
      int Pet::count = 0;         // 注意这一句,他起码做了两件事:创建内存区域并对其初始化 
      
      Pet::Pet(std::string theName)
      {
          name = theName;
          count++;
      
          std::cout << "一只宠物出生了,名字叫做: " << name << "
      ";
      }
      
      Pet::~Pet()
      {
          count--;
          std::cout << name << "挂掉了
      ";
      }
      
      int Pet::getCount()
      {
          return count;
      }
      
      Dog::Dog(std::string theName) : Pet(theName)
      {
          std::cout << "this:" << this << "
      ";
      }
      
      Cat::Cat(std::string theName) : Pet(theName)
      {
      }
      
      int main()
      {
          Dog dog("Tom");
          Cat cat("Jerry");
          std::cout << "dog:" << &dog << "
      ";
          std::cout << "
      已经诞生了" << Pet::getCount() << "只宠物!
      
      ";
      
          Dog dog_2("Tom_2");
          Cat cat_2("Jerry_2");
      
          std::cout << "
      现在呢,已经诞生了" << Pet::getCount() << "只宠物!
      
      ";
      
          std::cout << "
      现在还剩下 " << Pet::getCount() << " 只宠物!
      
      ";
      
          return 0;
      }
    • 静态方法也可以使用一个普通方法的调用语法来调用,但建议不要这么做,那会让代码变得更糟糕!
    • 请坚持使用:ClassName::methodName();

    • 请不要使用:objectName.methodName();

  • 相关阅读:
    HDU 5446 CRT+Lucas+快速乘
    awk的用法
    【福利】小程序开发资源干货汇总
    前端css常用的选择小汇
    前端css常用的选择小汇
    前端,Java,产品经理,微信小程序,Python等资源合集大放送
    前端,Java,产品经理,微信小程序,Python等资源合集大放送
    bootstrap+fileinput插件实现可预览上传照片功能
    bootstrap+fileinput插件实现可预览上传照片功能
    Jquery前端分页插件pagination同步加载和异步加载
  • 原文地址:https://www.cnblogs.com/tianqizhi/p/10399364.html
Copyright © 2011-2022 走看看