首先谈谈内存划分
内存大致可以划分为:
栈区 |
---|
堆区 |
全局/静态区 |
常量区 |
代码区 |
其中栈区位于高地址,代码区位于低地址。
代码区:存放程序代码段;
常量区:存放各种常量——数值常量和字符串常量等;
全局/静态区:存放全局变量和静态变量,未初始化的和初始化的分开存放;
堆区:使用new就是在该区申请;
栈区:存放局部变量等;
代码举例
// A.h文件
class A{
A(int a, int b); // 构造函数
~A(); // 析构函数
public:
int fuc1(); // 普通成员函数
// 静态函数可以在头文件中声明和定义,
// 即使该头文件被多次包含,也只会在内存中保存一份
static int fuc2() // 静态成员函数
{
return num1; // !错误,静态函数不能访问非静态变量
return num2;
}
protect:
private:
int num1; //普通成员变量
static int num2; //静态变量
}
// A.cpp文件
static int A::num2 = 1; // 静态成员变量初始化在类外面进行
int A::num2; // static关键字可以省略,num2不显示初始化时则为默认初始值,一般为0
// ps:静态成员变量的内存空间是在初始化时分配的
A::A(int a, int b)
{
num1 = a + b; // 普通成员变量初始化一般在构造函数中进行,不初始化则为垃圾值,一般为随机值
}
A::~A()
{
}
// 普通成员函数一般是不可以在头文件中定义的,只在头文件中声明,源文件中定义
// 因为一个成员函数只能定义一次,而可以声明多次(头文件被多次包含时)
int A::fuc1()
{
return num1+num2; // 普通成员函数既可以访问普通成员变量,也可以访问静态成员变量
}
// 静态函数也可以在源文件中定义
int A::fuc2()
{
return num2; // 在源文件中定义同样也只能访问静态变量
}
// main.cpp
#include "A.h"
int main()
{
// 访问静态成员变量有两种方法
// 方法1:按照普通成员变量访问方式——通过对象来访问
A a;
a.num2 = 10;
// 方法2:通过类来访问
A::num2 = 10;
// 类外调用public属性的静态成员函数同样有两种方法
// 方法1:按照普通public成员函数调用方式——通过对象来调用
a.fuc2();
// 方法2:通过类来调用
A::func2();
}
总结
1、普通成员变量一般在类的构造函数中初始化,而静态变量要在类外初始化;
2、普通成员函数可以访问所有类的变量,而静态函数只能访问静态变量;
3、普通成员函数一般只在头文件中声明,在源文件中定义;而静态函数可以在头文件中声明和定义,也可以将定义放在源文件中;
4、普通成员函数有this指针,而静态成员函数没有this指针,所以不能访问非静态成员变量;
5、类每构造一个对象,则每个对象都有各自不同的普通成员变量和函数;但所有对象共享一个静态成员变量和函数;
6、普通成员变量和函数随对象构造而构造,随对象销毁而销毁;但静态成员变量不随对象构造和销毁。