static在c++中

第一个例子,通过类名调用静态成员函数和非静态成员函数

 

class Point  

{  

public:   

    void init()  

    {    

    }  

    static void output()  

    {  

    }  

};  

void main()  

{  

    Point::init();  

    Point::output();  

}  

编译出错:error C2352: 'Point::init' : illegal call of non-static member function

 

结论1不能通过类名来调用类的非静态成员函数

 

 

第二个例子,通过类的对象调用静态成员函数和非静态成员函数

 

将上例的main()改为:

 

void main()  

{  

    Point pt;  

    pt.init();  

    pt.output();  

}  

编译通过。

 

结论2类的对象可以使用静态成员函数和非静态成员函数。

 

 

第三个例子,在类的静态成员函数中使用类的非静态成员

 

#include <stdio.h>  

class Point  

{  

public:  

Void point(){} 

    void init()  

    {    

    }  

    static void output()  

    {  

        printf("%d\n", m_x);  

    }  

private:  

    int m_x;  

};  

void main()  

{  

    Point pt;  

    pt.output();  

}  

编译出错:error C2597: illegal reference to data member 'Point::m_x' in a static member function

 

因为静态成员函数属于整个类,在类实例化对象之前就已经分配空间了,而类的非静态成员必须在类实例化对象后才有内存空间,所以这个调用就出错了,就好比没有声明一个变量却提前使用它一样。

 

结论3静态成员函数中不能引用非静态成员。

 

 

第四个例子,在类的非静态成员函数中使用类的静态成员

 

class Point  

{  

public:   

    void init()  

    {    

        output();  

    }  

    static void output()  

    {  

    }  

};  

void main()  

{  

    Point pt;  

    pt.output();  

}  

编译通过。

 

结论4类的非静态成员函数可以调用用静态成员函数,但反之不能。

 

 

第五个例子,使用类的静态成员变量

 

#include <stdio.h>  

class Point  

{  

public:   

    Point()  

    {    

        m_nPointCount++;  

    }  

    ~Point()  

    {  

        m_nPointCount--;  

    }  

    static void output()  

    {  

        printf("%d\n", m_nPointCount);  

    }  

private:  

    static int m_nPointCount;  

};  

void main()  

{  

    Point pt;  

    pt.output();  

}  

Ctrl+F7编译无错误,按F7生成EXE程序时报链接错误

 

error LNK2001: unresolved external symbol "private: static int Point::m_nPointCount" (?m_nPointCount@Point@@0HA)

 

这是因为类的静态成员变量在使用前必须先初始化。

 

main()函数前加上int Point::m_nPointCount = 0;

 

再编译链接无错误,运行程序将输出1

 

结论5:类的静态成员变量必须先初始化再使用。

 

 

 

 

 

结合上面的五个例子,对类的静态成员变量和成员函数作个总结:

 

一。静态成员函数中不能调用非静态成员。

 

二。非静态成员函数中可以调用静态成员。因为静态成员属于类本身,在类的对象产生之前就已经存在了,所以在非静态成员函数中是可以调用静态成员的。

 

三。静态成员变量使用前必须先初始化(int MyClass::m_nNumber = 0;),否则会在linker时出错。

<think>嗯,用户问的是C++中的static关键字的作用。我记得staticC++里有不同的用法,得仔细想想,别弄混了。首先,得确定用户的基础,可能是个刚开始学的,所以需要分点讲清楚,结构清晰。 首先,在过程式编程中的static,也就是在函数内部的局部变量。这时候static的作用是让变量的生命周期延长到整个程序运行期间,但作用域还是局限在函数内。比如,函数多次调用时,这个变量不会被重新初始化,而是保持上次的值。这个例子应该用计数器的例子比较直观,比如函数里的static int count =0,每次调用加一,这样每次调用count会递增。 然后是在全局变量或者函数外的静态变量。这时候static的作用是改变链接性,使得该变量只在当前文件内可见,防止其他文件引用。比如在多个源文件中,如果有同名的全局变量,加上static就可以避免重复定义的错误。这可能涉及到内部链接和外部链接的区别,需要解释清楚。 接下来是面向对象中的static成员变量和函数。静态成员变量属于整个类,而不是某个对象实例,所有对象共享同一个静态变量。比如可以用来统计类创建的实例数量。静态成员函数则属于类,不能访问非静态成员,只能访问静态成员。常用于工具函数或者操作静态变量。 另外,静态成员函数的特点是没有this指针,所以只能处理静态数据。比如类里有一个静态函数来获取实例数量,这时候就可以直接调用,不需要对象实例。 还要注意初始化的问题,静态成员变量需要在类外单独初始化,不能放在构造函数里。比如int Class::count =0; 这样。这点需要强调,避免用户犯错。 用户可能的问题可能包括:为什么有时候变量需要静态,或者在多文件项目中如何避免命名冲突,这时候静态全局变量就有用了。还有,静态成员函数和普通成员函数的区别,以及使用场景。 另外,可能要注意和C语言中static的区别,C++里的static在类中的用法是C没有的,而文件作用域的static在C和C++中类似。 还要检查是否有遗漏的情况,比如静态局部变量在C++11后的线程安全问题,不过可能用户暂时不需要深入这个层面。保持基础解释即可。 总结一下,应该分三个大点:过程式编程中的static变量,全局静态变量/函数,以及面向对象中的静态成员。每部分给出定义、作用、例子。这样结构清晰,用户容易理解。</think>在C++中,`static`关键字主要有以下三类作用,适用于不同场景: --- ### 一、过程式编程中的静态局部变量 - **作用**:延长局部变量的生命周期至程序结束,但作用域仍限于函数内。 - **特点**:首次调用时初始化,后续调用保留上次的值。 - **示例**: ```cpp void counter() { static int count = 0; // 只会初始化一次 count++; std::cout << "调用次数:" << count << std::endl; } ``` 多次调用`counter()`会输出递增的数值,如`1, 2, 3...` --- ### 二、全局作用域的静态变量/函数 - **作用**:限制全局变量或函数的链接性(*内部链接*),使其仅在当前文件可见。 - **意义**:避免多文件项目中的命名冲突。 - **示例**: ```cpp // File1.cpp static int globalVar = 10; // 其他文件无法访问此变量 static void helper() { // 其他文件无法调用此函数 // ... } ``` --- ### 三、面向对象中的静态成员 #### 1. 静态成员变量 - **作用**:属于类本身,所有对象共享同一份数据。 - **初始化**:需在类外单独定义(C++17后支持`inline static`)。 - **示例**: ```cpp class MyClass { public: static int count; // 声明 }; int MyClass::count = 0; // 类外初始化 ``` 通过`MyClass::count`直接访问,或通过对象访问。 #### 2. 静态成员函数 - **作用**:属于类本身,无需对象实例即可调用。 - **限制**:不能访问非静态成员(无`this`指针)。 - **示例**: ```cpp class MyClass { public: static void printCount() { std::cout << "实例数:" << count << std::endl; } }; MyClass::printCount(); // 直接通过类调用 ``` --- ### 总结表格 | 场景 | 作用 | 典型用途 | |---------------------|-------------------------------|----------------------------| | 局部变量 | 保留状态 | 计数器、缓存 | | 全局变量/函数 | 限制文件内可见性 | 隐藏实现细节 | | 类的静态成员变量 | 共享数据 | 统计实例数量、配置参数 | | 类的静态成员函数 | 提供类级别操作 | 工具函数、工厂方法 | 理解`static`的关键是区分其在不同上下文中如何控制**生命周期**和**作用域**。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值