注:若没有特指是 静态成员时,默认都是普通成员;

1 类中的普通成员

  类中的成员变量 和 成员函数 是分开存储的。其中,

    1)每个对象都有独立的成员变量;成员变量可以存储在 栈空间、堆空间、全局数据区;

    2)所有对象共享类的成员函数;成员函数 只能存储在 代码段;

2 类中的静态成员(static)

  类中的静态成员

    1、用 static关键字 修饰;

    2、可以用 类名::成员名  访问 静态成员;

    3、静态成员  属于  整个类;

    4、静态成员 是所属类的成员,其它类不能访问;

    5、静态成员的内存分配 是 唯一的;

  1) 静态成员变量

    特征:1、静态成员变量  属于  整个类所有;

       2、静态成员变量的生命周期不依赖任何对象;(静态成员变量的生命周期在程序的运行期)

       3、所有对象共享类的静态成员变量;

       4、可以通过  类名  直接访问公有的静态成员变量;

       5、可以通过 对象名  访问公有的静态成员变量;

       6、静态成员变量  需要在类外单独分配空间;(类内声明、类外定义并初始化)

          7、静态成员变量  在程序内部位于全局数据区,不计入类的内存计算。

    原因/好处:使用静态成员变量实现多个对象之间的数据共享不会破坏隐藏的原则,保证了安全性还可以节省内存。

    使用方法:

      1、在类的内部,使用 static 修饰普通成员变量;

      2、在类的外部(全局作用域),使用 Type ClassName::VarName = value 初始化,并申请存储空间;

         注:静态成员变量不属于类的任何对象,所以并不是对象建立时被定义的,所以它不能由类的构造函数初始化,一般也不能在类内初始化;

 /*
静态成员变量 只能在类的内部声明,在类的外部(全局区)定义和初始化;
*/ #include <iostream> using namespace std; class Test{
public:
int GetA() const{return a;}
private:
static int a; // 静态成员变量
};
//int Test::a;如果这样定义不赋予初值,则初值为零
int Test::a = ; int main(int argc, char *argv[])
{
Test T; cout << T.GetA() << endl; return ;
}

  静态成员变量 被类的所有对象共享,包括派生类对象;

 #include <iostream>

 using namespace std;

 class Base{
public:
static int a; // 静态成员变量
}; // int Test::a;如果这样定义不赋予初值,则初值为零
int Base::a; class Derived : public Base{ }; int main(int argc, char *argv[])
{
Base B;
Derived D; B.a++;
cout << B.a << endl; //
D.a++;
cout << D.a << endl; // return ;
}

  静态成员变量可以作为普通成员函数的默认形参,而普通成员变量则不可以;

 class Test{
public:
static int a; //静态成员变量
int b;
void fun_1(int i = a); //正确
//void fun_2(int i = b); //报错
};

  静态成员变量的类型 可以是所属类的类型,而普通成员变量则不可以。普通成员变量只能声明为 所属类类型的 指针或引用;

 class Test{
public:
static Test a; //正确
Test b; //报错
Test *pTest; //正确
Test &m_Test; //正确
static Test *pStaticObject; //正确
};

  静态成员变量在const函数中可以修改,而普通的成员变量是万万不能修改的;

 /*
  const修饰的是当前this指针所指向的对象是const,但是静态成员变量不属于任何类的对象,它被类的所有对象修改,所以this指针不修饰静态的成员变量,所以可以更改。
*/
class Test{
public:
static int a;
int b;
public:
Test():b(){}
void test() const
{
a++;
//b++; // err // const指的是不能修改当前调用该函数对象的成员变量
}
}; int Test::a;

 2)静态成员函数

    特征:1、静态成员函数  属于  整个类所有;

       2、所有对象共享类的静态成员函数;

       2、可以通过  类名  直接访问公有的静态成员函数;

       3、可以通过 对象名  访问公有的静态成员函数;

       4、静态成员函数 只能 访问静态成员,不能访问  非静态成员;

       5、静态成员函数没有this指针,也就是说静态成员函数不能使用修饰符(也就是函数后面的const关键字);

    原因:处理静态成员变量; 

    使用方法:直接用 static 修饰 普通成员函数(类内声明时),不需要 static 修饰(类外定义时);

    总结:

    案例分析:

 /**
* 统计某班选修课考试的平均成绩
*/ #include <iostream>
#include <string> using namespace std; class Student
{
private:
string name; // 姓名
string gender; // 性别
float score; // 分数
string subject; // 课程
static float chinese_scores; // 语文分数
static float math_scores; // 数学分数
public:
static int total_counts; // 总人数
static int chinese_counts; // 语文课人数
static int math_counts; // 数学课人数
public:
Student(string name, string gender, float score, string subject);
~Student();
static float aveScores(string subject);
void printStudentInfo();
void printAveScores();
};
int Student::total_counts = ;
float Student::chinese_scores = ;
int Student::chinese_counts = ;
float Student::math_scores = ;
int Student::math_counts = ; Student::Student(string name, string gender, float score, string subject)
{
this->name = name;
this->gender = gender;
this->score = score;
this->subject = subject; if(subject == "chinese" || subject == "语文")
{
chinese_scores += score;
chinese_counts++;
}
else if(subject == "math" || subject == "数学")
{
math_scores += score;
math_counts++;
}
else
{
cout << "this is no the subect:" << subject << endl;
}
total_counts++;
} Student::~Student()
{
total_counts--; if(subject == "chinese" || subject == "语文")
{
chinese_counts--;
}
if(subject == "math" || subject == "数学")
{
math_counts--;
}
} float Student::aveScores(string subject)
{
float ave_score = ; if(chinese_counts > && subject == "chinese" || subject == "语文")
{
ave_score = (chinese_scores / chinese_counts);
//cout << subject << "\t" << chinese_counts << "\t" << chinese_scores << endl;
}
else if(math_counts > && subject == "math" || subject == "数学")
{
ave_score = (math_scores / math_counts);
//cout << subject << "\t" <<math_counts << "\t" << math_scores << endl;
} return ave_score;
} void Student::printStudentInfo()
{
cout << name << "\t" << gender << "\t" << score << "\t" << subject << endl;
} void Student::printAveScores()
{
cout <<subject << " average score: " << aveScores(subject) << endl;
} void function()
{
const int SIZE = ;
Student stu[SIZE] =
{
Student("", "male", , "语文"),
Student("", "male", , "数学"),
Student("", "male", , "数学"),
Student("", "male", , "语文"),
Student("", "male", , "语文"),
}; for(int i = ; i < SIZE; i++)
{
stu[i].printStudentInfo();
} stu[].printAveScores();
stu[].printAveScores(); cout << "语文" << " average score: " << Student::aveScores("语文") << endl;
cout << "数学" << " average score: " << Student::aveScores("数学") << endl; cout << "总人数: " << Student::total_counts << endl;
} int main(int argc, char const *argv[])
{
function(); cout << "语文课人数: " << Student::chinese_counts << endl;
cout << "数学课人数: " << Student::math_counts << endl;
cout << "总人数: " << Student::total_counts << endl; return ;
}

静态成员的案例1

 /**
* 案例:有一场篮球赛,红队与蓝队各有5名队员,统计各个球队的得分情况(总分、平均分),并将获胜球队的球员信息输出
*/ #include <iostream>
#include <string> using namespace std; class Player
{
public:
int number; // 编号
string gender; // 性别
int age; // 年龄
float score; // 个人分数 public:
Player(int number = , int age = , float score = , string gender = "male")
{
this->number = number;
this->age = age;
this->score = score;
this->gender = gender;
}
}; class Team
{
private:
string name; // 球队名称
int sum; // 球队总分 //static int COUNT; // 球队人数
static const int COUNT = ; // 球队人数
Player player[COUNT]; // 球队队员信息
public:
Team(string name)
{
this->name = name;
for(int i = ; i < Team::COUNT; i++)
{
player[i] = Player( + i, + i, );
}
}
string getName()
{
return name;
}
static int playersCount()
{
return COUNT;
}
int totalScore()
{
sum = ;
for(int i = ; i < Team::COUNT; i++)
{
sum += player[i].score;
} return sum;
}
float aveScore()
{
if(sum == )
{
totalScore();
}
return (sum/Team::COUNT);
}
bool setPlayer(int index, int num, int age, float score, bool isMale = true)
{
bool ret = true; if(Team::COUNT && index >= )
{
player[index].number = num;
player[index].age = age;
player[index].score = score;
isMale == true ? player[index].gender = "male" : player[index].gender = "female";
}
else
{
cout << "the index of array is out of range, the max index should less than " << Team::COUNT << endl;
ret = false;
} return ret;
}
bool PK(Team &team)
{
int ret = this->sum > team.sum; if(ret)
{
cout << this->name + " 获胜" << endl;
}
else
{
cout << team.name + " 获胜" << endl;
} return ret;
}
void print()
{
cout << "Team Name:" << name << endl;
for(int i = ; i < Team::COUNT; i++)
{
cout << player[i].number << "\t" << player[i].gender << "\t" << player[i].age << "\t" << player[i].score << endl;
}
cout << name << " get total score:" << totalScore() << endl;
cout << name << " get average score:" << aveScore() << endl;
} };
//int Team::COUNT = 5; // 初始化每支球队共有5名球员 int main(int argc, char *argv[])
{
Team t1("Red Team"); t1.setPlayer(, , , );
t1.setPlayer(, , , );
t1.setPlayer(, , , );
t1.setPlayer(, , , , false);
t1.setPlayer(, , , );
// t1.print();
// cout << t1.getName() << " get total score:" << t1.totalScore() << endl;
// cout << t1.getName() << " get average score:" << t1.aveScore() << endl; cout << endl; Team t2("Blue Team"); t2.setPlayer(, , , );
t2.setPlayer(, , , );
t2.setPlayer(, , , );
t2.setPlayer(, , , );
t2.setPlayer(, , , );
// t2.print();
// cout << t2.getName() << " get total score:" << t2.totalScore() << endl;
// cout << t2.getName() << " get average score:" << t2.aveScore() << endl; if( t1.PK(t2) )
{
t1.print();
}
else
{
t2.print();
} return ;
}

静态成员的案例2

c++中的 static 关键字的更多相关文章

  1. (转)Java中的static关键字解析

    转载: http://www.cnblogs.com/dolphin0520/p/3799052.html 一.static关键字的用途 在<Java编程思想>P86页有这样一段话: &q ...

  2. 关于Java中的static关键字

    Java中的 static 关键字,确实是一个关键的字(key word),今天就来总结一下它的用法,说说为什么关键. Java中的 static 关键字主要是用来做内存管理的.理解了这句话才能够比较 ...

  3. Java中的static关键字解析

    Java中的static关键字解析 static关键字是很多朋友在编写代码和阅读代码时碰到的比较难以理解的一个关键字,也是各大公司的面试官喜欢在面试时问到的知识点之一.下面就先讲述一下static关键 ...

  4. C++中的static关键字的总结

    C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static.前者应用于普通变量和函数,不涉及类:后者主要说明static在类中的作用. 1.面向过程设计中的st ...

  5. (转)Java中的static关键字解析

    转自http://www.cnblogs.com/dolphin0520/p/3799052.html 一.static关键字的用途 在<Java编程思想>P86页有这样一段话: “sta ...

  6. (转)C++中的static关键字的总结

    文章转自 http://www.cnblogs.com/BeyondAnyTime/archive/2012/06/08/2542315.html C++的static有两种用法:面向过程程序设计中的 ...

  7. Java中的static关键字解析 转载

    原文链接:http://www.cnblogs.com/dolphin0520/p/3799052.html Java中的static关键字解析 static关键字是很多朋友在编写代码和阅读代码时碰到 ...

  8. c++中关于static关键字的问题

    C++的static关键字C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static.前者应用于普通变量和函数,不涉及类:后者主要说明static在类中的作用. ...

  9. C++中的static关键字(转)

    原出处:http://blog.csdn.net/hackbuteer1/article/details/7487694 C++的static有两种用法:面向过程程序设计中的static和面向对象程序 ...

  10. Java中的static关键字解析(转自海子)__为什么main方法必须是static的,因为程序在执行main方法的时候没有创建任何对象,因此只有通过类名来访问。

    Java中的static关键字解析 static关键字是很多朋友在编写代码和阅读代码时碰到的比较难以理解的一个关键字,也是各大公司的面试官喜欢在面试时问到的知识点之一.下面就先讲述一下static关键 ...

随机推荐

  1. HTTP请求中的GET-POST方式

    目录 一.前言部分(概念) 二.对比 GET 与 POST 二者最大的差异 GET 与 POST 请求本质上并无区别 深层了解:POST 请求产生两个数据包? 三.两种请求方式如何灵活使用? 四.常见 ...

  2. Using TFRecords and tf.Example

    -----这篇其实是TensorFlow的官方tutorials,由于没有翻译,笔者姑且翻译一下,用来日后思考.------- 原址:https://www.tensorflow.org/tutori ...

  3. Bandicam(班迪录屏)高清视频录制工具

    Bandicam(班迪录屏)简单好用的录屏幕,录游戏,录视频的功能强大的屏幕录像软件,比起其他软件其性能更加卓越. 与其他软件相比,用Bandicam录制的视频大小更小, 不仅保证原文件的质量.

  4. Java小项目之:五子棋,你下棋下得过电脑吗?

    Java小项目之:五子棋,你下棋下得过电脑吗? Java五子棋功能要求: 1.创建窗口和设计一个棋盘界面 2.实现鼠标点击,棋子出现,黑白棋轮流下 3.能够判断五子相连输赢 4.添加重新开始,悔棋,退 ...

  5. BFS小记

    题目:求从S走到G点所需步数 #S######.#......#..#.#.##.##.#.#........##.##.####....#....#.#######.#....#......#### ...

  6. 输入n个字符串,找出最长最短字符串(若有个数相同的,都打印出来)

    首先,要求找到最长最短字符串,我们应该用数组将其存起来,输入的个数是不固定的,我们就可以用Scanner获取要输入的个数,最终找到的个数也不固定,我们可以封装两个方法,并且返回值类型为数组. 我遇到的 ...

  7. Java类成员之属性

    属性含义:对应类中的成员变量. 语法格式:修饰符 数据类型 属性名 = 初始化值; 1.修饰符常用的有权限修饰符(private.default.protected.public) 以及其他修饰符(s ...

  8. 为什么说ArrayList是线程不安全的?

    一.概述 对于ArrayList,相信大家并不陌生.这个类是我们平时接触得最多的一个列表集合类. 面试时相信面试官首先就会问到关于它的知识.一个经常被问到的问题就是:ArrayList是否是线程安全的 ...

  9. 使用read、readline、readlines和pd.read_csv、pd.read_table、pd.read_fwf、pd.read_excel获取数据

    从文本文件读取数据 法一: 使用read.readline.readlines读取数据 read([size]):从文件读取指定的字节数.如果未给定或为负值,则去取全部.返回数据类型为字符串(将所有行 ...

  10. 深入学习MySQL 01 一条查询语句的执行过程

    在学习SpringCloud的同时,也在深入学习MySq中,听着<mysql45讲>,看着<高性能MySQL>,本系列文章是本人学习过程的总结,水平有限,仅供参考,若有不对之处 ...