Static member functions in C++

In the previous lesson on static member variables, you learned that classes can have member variables that are shared across all objects of that class type. However, what if our static member variables are private? Consider the following example:

class Something
{
private:
    static int s_nValue;
 
};
 
int Something::s_nValue = 1; // initializer
 
int main()
{
    // how do we access Something::s_nValue?
}
In this case, we can’t access Something::s_nValue directly from main(), because it is private. Normally we access private members through public member functions. While we could create a normal public member function to access s_nValue, we’d then need to instantiate an object of the class type to use the function! We can do better. In this case, the answer to the problem is that we can also make member functions static.

Like static member variables, static member functions are not attached to any particular object. Here is the above example with a static member function accessor:

class Something
{
private:
    static int s_nValue;
public:
    static int GetValue() { return s_nValue; }
};
 
int Something::s_nValue = 1; // initializer
 
int main()
{
    std::cout << Something::GetValue() << std::endl;
}
Because static member functions are not attached to a particular object, they can be called directly by using the class name and the scope operator. Like static member variables, they can also be called through objects of the class type, though this is not recommended.

Static member functions have two interesting quirks worth noting. First, because static member functions are not attached to an object, they have no this pointer! This makes sense when you think about it — the this pointer always points to the object that the member function is working on. Static member functions do not work on an object, so the this pointer is not needed.

Second, static member functions can only access static member variables. They can not access non-static member variables. This is because non-static member variables must belong to a class object, and static member functions have no class object to work with!

Here’s another example using static member variables and functions:

class IDGenerator
{
private:
    static int s_nNextID;
 
public:
     static int GetNextID() { return s_nNextID++; }
};
 
// We'll start generating IDs at 1
int IDGenerator::s_nNextID = 1;
 
int main()
{
    for (int i=0; i < 5; i++)
        cout << "The next ID is: " << IDGenerator::GetNextID() << endl;
 
    return 0;
}

This program prints:

The next ID is: 1
The next ID is: 2
The next ID is: 3
The next ID is: 4
The next ID is: 5

Note that because all the data and functions in this class are static, we don’t need to instantiate an object of the class to make use of it’s functionality! This class utilizes a static member variable to hold the value of the next ID to be assigned, and provides a static member function to return that ID and increment it.

Be careful when writing classes with all static members like this. Although such “pure static classes” can be useful, they also come with some potential downsides. First, because all of the members belong to the class, and the class is accessible from anywhere in the program, it’s essentially the equivalent of declaring a global variable of the class type. In the section on global variables, you learned that global variables are dangerous because one piece of code can change the value of the global variable and end up breaking another piece of seemingly unrelated code. The same holds true for pure static classes. Second, because all static members are instantiated only once, there is no way to have multiple copies of a pure static class (without cloning the class and renaming it). For example, if you needed two independent IDGenerators, this would not be possible.


from http://www.learncpp.com/cpp-tutorial/812-static-member-functions/

C++中,`static`关键字有多个作用,主要用于存储类别(storage class)和作用域控制。以下是静态关键字的主要用途: 1. 静态存储类别(Storage Class): - **Static Local Variables**: 在函数内部使用`static`声明的变量,其生命周期从定义开始直到程序结束,且仅有一个副本,即使函数被多次调用。这意味着它们只在首次调用时初始化,后续调用时保持不变。 - **Static Member Variables**(Class Variables):类中的静态成员变量在整个类实例化期间共享,无论创建了多少个对象,每个对象都有自己的静态成员函数的引用。 - **Static Member Functions**: 类中的静态成员函数不依赖于类的任何实例,可以直接通过类名调用。 2. 静态局部作用域: - 当静态变量出现在函数或代码块的开始时,它只在当前作用域可见,每次进入该作用域都会初始化一次。 3. 文件全局(File Scope): - 在头文件(`.h`)中声明的静态变量或函数,会在整个程序中全局可见,但仅在一个编译单元(translation unit)内初始化一次。 4. 内联函数: - `inline`关键字配合`static`可以提高内联函数的性能,因为编译器可能会在所有调用的地方直接替换内联代码,而不仅仅是`inline`声明的一次。 5. 链表节点的静态属性: - 在某些数据结构如静态链表中,静态成员可用于表示链表的头部或尾部元素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值