静态成员函数调用非静态成员变量

本文详细解释了C++中静态成员(包括静态变量和静态函数)的概念及其使用方法,对比了静态成员与非静态成员的区别,并通过具体示例展示了如何在类中正确地声明和初始化静态成员。
程序最终都将在内存中执行,变量只有在内存中占有一席之地时才能被访问。
   类的静态成员(变量和函数(方法))属于类本身,在类加载的时候就会分配内存,可以通过类名直接去访问;
   非静态成员(变量和函数(方法))属于类的对象,所以只有在类的对象产生(创建类的实例)时才会分配内存,然后通过类的对象(实例)去访问。
   在一个类的静态成员中去访问其非静态成员之所以会出错是因为在类的非静态成员不存在的时候类的静态成员就已经存在了,访问一个内存中不存在的东西当然会出错。
   C++会区分两种类型的成员函数:静态成员函数和非静态成员函数。这两者之间的一个重大区别是,静态成员函数不接受隐含的this自变量。所以,它就无法访问自己类的非静态成员。

静态数据成员
   在类中,静态成员可以实现多个对象之间的数据共享,并且使用静态数据成员还不会破坏隐藏的原则,即保证了安全性。因此,静态成员是类的所有对象中共享的成员,而不是某个对象的成员。使用静态数据成员可以节省内存,因为它是所有对象所公有的,因此,对多个对象来说,静态数据成员只存储一处,供所有对象共用。静态数据成员的值对每个对象都是一样,但它的值是可以更新的。只要对静态数据成员的值更新一次,保证所有对象存取更新后的相同的值,这样可以提高时间效率。
静态数据成员的使用方法和注意事项如下:
1、静态数据成员在定义或说明时前面加关键字static。
2、静态成员初始化与一般数据成员初始化不同。静态数据成员初始化的格式如下:
     <数据类型><类名>::<静态数据成员名>=<值>
这表明:
     (1) 初始化在类体外进行,而前面不加static,以免与一般静态变量或对象相混淆。
     (2) 初始化时不加该成员的访问权限控制符private,public等。
     (3) 初始化时使用作用域运算符来标明它所属类,因此,静态数据成员是类的成员,而不是对象的成员。
3、静态数据成员是静态存储的,它是静态生存期,必须对它进行初始化。
4、引用静态数据成员时,采用如下格式:
     <类名>::<静态成员名>
静态成员函数
   静态成员函数和静态数据成员一样,它们都属于类的静态成员,它们都不是对象成员。因此,对静态成员的引用不需要用对象名。在静态成员函数的实现中不能直接引用类中说明的非静态成员,可以引用类中说明的静态成员。如果静态成员函数中要引用非静态成员时,可通过对象来引用。下面通过例子来说明这一点。
#include <iostream>
using namespace std;
class Thornbird
{
  public:
     Thornbird(int a)
     {
        m=a;
        n+=a;
     }
     static void f1(Thornbird t);

  private:
     int m;
     static int n;
};

void Thotnbird::f1(Thornbird t)
{
     cout<<"m="<<t.m<<endl; //静态成员函数中通过对象来引用非静态成员
     cout<<"n="<<n<<endl;
}

int Thornbird::n=0; //静态数据成员初始化的格式<数据类型><类名>::<静态数据成员名>=<值>

void main()
{
     Thornbird C1(3),C2(28);
     Thornbird::f1(C1); //静态成员函数调用时不用对象名
     Thornbird::f1(C2);
}
我们可以自行先分析其结果。从中可看出,调用静态成员函数使用如下格式:
<类名>::<静态成员函数名>(<参数表>);
运行结果:
m=3
n=31
m=28
n=31

### 静态成员函数与静态成员函数的调用方式差异 在 C++ 中,静态成员函数和静态成员函数是中两种不同的成员函数型,它们的调用方式存在显著差异。以下是两者的调用方式及其特点的详细对比: #### 1. 调用方式 - **静态成员函数** 静态成员函数属于本身,而不属于某个具体的对象实例。因此,它可以使用名直接调用,而无需创建对象实例。例如: ```cpp class MyClass { public: static void staticFunction() { // 静态成员函数实现 } }; MyClass::staticFunction(); // 使用名直接调用静态成员函数[^1] ``` - **静态成员函数** 静态成员函数属于的具体对象实例,必须通过对象实例来调用。这是因为静态成员函数需要访问 `this` 指针,而 `this` 指针指向的是调用该函数的具体对象实例。例如: ```cpp class MyClass { public: void nonStaticFunction() { // 静态成员函数实现 } }; MyClass obj; obj.nonStaticFunction(); // 必须通过对象实例调用静态成员函数[^2] ``` #### 2. 对象依赖性 - **静态成员函数** 静态成员函数不依赖于任何对象实例,因此它无法访问静态成员变量静态成员函数。这是由于静态成员函数没有隐式的 `this` 指针,也就无法引用具体对象的成员。例如: ```cpp class MyClass { private: int x; public: static void staticFunction() { // 不能访问 x 或静态成员函数 } }; ``` - **静态成员函数** 静态成员函数依赖于具体的对象实例,可以通过 `this` 指针访问对象静态成员变量和其他静态成员函数。例如: ```cpp class MyClass { private: int x; public: void nonStaticFunction() { x = 10; // 可以访问静态成员变量 x } }; ``` #### 3. 相互调用限制 - **静态成员函数调用静态成员函数** 静态成员函数无法直接调用静态成员函数,因为静态成员函数没有 `this` 指针,无法确定调用哪个对象静态成员函数。如果需要调用静态成员函数,则必须显式传递一个对象指针或引用。例如: ```cpp class MyClass { public: void nonStaticFunction() {} static void staticFunction(MyClass& obj) { obj.nonStaticFunction(); // 显式通过对象调用静态成员函数[^2] } }; ``` - **静态成员函数调用静态成员函数** 静态成员函数可以直接调用静态成员函数,因为它可以通过名访问静态成员函数,无需依赖 `this` 指针。例如: ```cpp class MyClass { public: static void staticFunction() {} void nonStaticFunction() { staticFunction(); // 直接调用静态成员函数[^3] } }; ``` ### 示例代码 以下是一个综合示例,展示了静态成员函数和静态成员函数的调用方式及相互调用的实现: ```cpp #include <iostream> using namespace std; class MyClass { private: int x; public: static void staticFunction() { cout << "This is a static function." << endl; } void nonStaticFunction() { cout << "This is a non-static function." << endl; staticFunction(); // 静态成员函数调用静态成员函数 } static void callNonStaticFunction(MyClass& obj) { obj.nonStaticFunction(); // 静态成员函数通过对象调用静态成员函数 } }; int main() { MyClass::staticFunction(); // 使用名调用静态成员函数 MyClass obj; obj.nonStaticFunction(); // 使用对象调用静态成员函数 MyClass::callNonStaticFunction(obj); // 静态成员函数调用静态成员函数 return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值