C++ 类中的静态变量和静态成员函数

本文通过多个示例详细解析了静态成员的使用方式及注意事项,包括静态成员函数如何正确调用及静态成员变量的初始化等问题。
静态数据成员:
下面看一个例子:
#include <iostream.h>
class Point
{
public:
void output()
{
}
static void init()
{
}
};
void main( void )
{
Point pt;
pt.init();
pt.output();
}
这样编译是不会有任何错误的。
下面这样看
#include <iostream.h>
class Point
{
public:
void output()
{
}
static void init()
{
}
};
void main( void )
{
Point::output();
}
这样编译会处错,错误信息:illegal call of non-static member function,为什么?
因为在没有实例化一个类的具体对象时,类是没有被分配内存空间的。
好的再看看下面的例子:
#include <iostream.h>
class Point
{
public:
void output()
{
}
static void init()
{
}
};
void main( void )
{
Point::init();
}
这时编译就不会有错误,因为在类的定义时,它静态数据和成员函数就有了它的内存区,它不属于类的任何一个具体对象。
好的再看看下面的例子:
#include <iostream.h>
class Point
{
public:
void output()
{
}
static void init()
{
x = 0;
y = 0;
}
private:
int x;
int y;
};
void main( void )
{
Point::init();
}
编译出错:
illegal reference to data member 'Point::x' in a static member function
illegal reference to data member 'Point::y' in a static member function
在一个静态成员函数里错误的引用了数据成员,
还是那个问题,静态成员(函数),不属于任何一个具体的对象,那么在类的具体对象声明之前就已经有了内存区,
而现在非静态数据成员还没有分配内存空间,那么这里调用就错误了,就好像没有声明一个变量却提前使用它一样。
也就是说在静态成员函数中不能引用非静态的成员变量。
好的再看看下面的例子:
#include <iostream.h>
class Point
{
public:
void output()
{
x = 0;
y = 0;
init();
}
static void init()
{

}
private:
int x;
int y;
};
void main( void )
{
Point::init();
}
好的,这样就不会有任何错误。这最终还是一个内存模型的问题,
任何变量在内存中有了自己的空间后,在其他地方才能被调用,否则就会出错。
好的再看看下面的例子:
#include <iostream.h>
class Point
{
public:
void output()
{
}
static void init()
{
x = 0;
y = 0;
}
private:
static int x;
static int y;
};
void main( void )
{
Point::init();
}
编译:
Linking...
test.obj : error LNK2001: unresolved external symbol "private: static int Point::y" (?y@Point@@0HA)
test.obj : error LNK2001: unresolved external symbol "private: static int Point::x" (?x@Point@@0HA)
Debug/Test.exe : fatal error LNK1120: 2 unresolved externals
执行 link.exe 时出错.
可以看到编译没有错误,连接错误,这又是为什么呢?
这是因为静态的成员变量要进行初始化,可以这样:
#include <iostream.h>
class Point
{
public:
void output()
{
}
static void init()
{
x = 0;
y = 0;
}
private:
static int x;
static int y;
};
int Point::x = 0;
int Point::y = 0;
void main( void )
{
Point::init();
}
在静态成员数据变量初始化之后就不会出现编译错误了。
再看看下面的代码:
#include <iostream.h>
class Point
{
public:
void output()
{
}
static void init()
{
x = 0;
y = 0;
}
private:
static int x;
static int y;
};
void main( void )
{
}
编译没有错误,为什么?
即使他们没有初始化,因为我们没有访问x,y,所以编译不会出错。
<think>我们正在处理关于C++静态成员变量函数的查询。根据引用内容,我们可以总结以下几点: 1. 静态成员变量: - 属于本身,而不是的实例。所有实例共享同一个静态成员变量。 - 在内声明,但必须在外进行定义初始化(使用作用域解析运算符)。 - 在程序开始运行(main函数执行之前)就分配存储空间,直到程序结束才释放。 - 可以通过名直接访问,也可以通过对象访问。 2. 静态成员函数: - 属于本身,而不是的实例。 - 只能访问静态成员静态成员变量静态成员函数),不能访问非静态成员(因为非静态成员需要对象实例才能确定)。 - 没有this指针(因为不依赖于具体对象)。 - 可以通过名直接调用,也可以通过对象调用。 我们将根据这些要点组织回答,并使用示例代码进行说明。注意,我们的回答需要包含引用的标识(如[^1]等)。 由于引用中已经提供了部分代码,我们将引用这些代码并添加注释说明。 下面开始组织回答: </think>### C++静态成员变量与静态成员函数详解 #### **一、静态成员变量的定义与特点** 1. **定义方式** - 内声明:使用 `static` 关键字声明 - 外初始化:**必须**在全局作用域单独初始化(无 `static` 关键字) ```cpp class Student { public: static int m_total; // 内声明 }; int Student::m_total = 0; // 外初始化(分配内存)[^1][^2] ``` 2. **核心特性** - **共享存储**:所有实例共享同一内存空间,生命周期贯穿整个程序 - **独立于对象**:不占用对象内存空间,通过 `名::变量名` 直接访问 - **初始化时机**:在 `main()` 函数执行前完成初始化[^2] #### **二、静态成员函数的使用规则** 1. **定义与调用** ```cpp class Person { public: static void func() { cout << "静态函数调用" << endl; } }; // 通过名直接调用 Person::func(); // ✅ 无需创建对象[^3][^4] ``` 2. **访问权限限制** - **只能访问静态成员**:无 `this` 指针,无法访问非静态成员 ```cpp static void func() { m_A = 100; // ✅ 可修改静态变量 // m_B = 200; // ❌ 错误!无法访问非静态成员[^4] } ``` #### **三、典型应用场景** 1. **跨对象数据共享** - 例如统计已创建的对象数量: ```cpp class Student { public: Student() { m_total++; } // 构造函数中计数 static int getTotal() { return m_total; } private: static int m_total; }; ``` 2. **工具实现** - 创建不依赖对象实例的工具函数(如数学计算库) #### **四、注意事项** 1. **存储隔离** - 静态成员变量存储在全局数据区,非静态成员在对象堆栈中[^2] 2. **访问控制** - 静态成员函数/变量仍受 `private/protected` 访问权限约束[^4] 3. **线程安全** - 多线程环境中需额外同步机制(如互斥锁) --- ### 示例代码分析 ```cpp #include <iostream> using namespace std; class Counter { public: Counter() { count++; } static int getCount() { return count; } // 静态函数返回静态变量 private: static int count; // 声明静态变量 }; int Counter::count = 0; // 外初始化 int main() { Counter c1, c2; cout << "已创建对象数: " << Counter::getCount(); // 输出: 2 return 0; } ``` > 代码说明:所有 `Counter` 对象共享 `count` 变量,通过静态函数 `getCount()` 直接访问[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值