自学内容网 自学内容网

C++ 关于静态成员对象、函数学习整理:

类的静态成员为类创建的所有对象所共有的成员,不单独属于某一对象,而属于整个类,而静态成员分为静态成员变量、静态成员函数。

静态成员变量(静态数据成员):

引入及解决问题的优势:

类创建了多个对象,对象的具体成员对象各不相干,而在大量对象的基础上,出现了一部分共有属性的对象

(例如:

1、银行系统中,用户作为单独对象时,成员变量中,银行储存利率为所有用户公有一致的对象成员;

2、班级系统所有同学作为单独变量,需统计班级莫科目总分,该成员属于全体公有不属于单一对象

由上面引例了解到以上两种情况如设置为普通对象的成员:

例1:浪费了大量地址空间去存储一致的对象成员

例2:全班总分数对每一个同学单一的对象而言成员没有实际意义,而在每位同学对象依次录入成绩的同时总成绩变化,如何更改之前每个对象的总成绩?引发大量重复修改值的操作

因此优化引出静态成员变量的概念:

  1. 多个同类对象共用静态成员变量,节约空间
  2. 多个同类对象共用静态成员变量,一改全改便于维护

静态成员变量的定义及初始化:

声明(类内):

static 类型名 静态成员变量名;

定义、初始化(类外): 

类型 类名::静态成员变量 = 初始化值;//初始化

在初始化时需要区分静态变量是否为整数类型,不同的类型决定了初始化位置不同。

  • 整数类型的静态成员变量可以在定义或声明中的某一处完成初始化,但不能同时在两处进行初始化,即便初始化的值是相同的也不行。
  • 非整数类型的静态成员变量则必须且只能在定义语句中进行初始化,类内的声明语句中不允许初始化操作。
  • 类内声明,类外初始化定义
    //1.如何对静态成员变量进行初始化?
    // 
    class A
    {
    //静态成员变量类型为整型:
    //可以在声明处初始化(仅静态常量!),也可在定义处初始化
    const static int a = 10; //仅静态常量!
    static int b;//普通静态成员变量只能在类外初始化
    
    //静态成员变量类型非整型,只能在类外定义处初始化
    static string c;
    };
    int A::b = 10;
    string A::c = "hello";

注意:

  • 静态成员变量在类外初始化,不能在类内构造函数初始化;
    • 因为静态成员变量不属于某一个对象,而单属于类(或全体对象),普通成员在类内的构造函数内初始化,二者需区分开;
    • 如果可以在类的构造函数中初始化,那么每创建一个对象,静态成员变量就要被初始化一次,这显然是错误的;
  • 静态成员变量仅在 定义的时有static,初始化时没有static;
  • 静态成员变量为私有类型,在类外初始化,类外并不在类外成员函数内,所以满足private访问规则;
  • 初始化时使用作用域运算符标明所属类。

静态成员变量的使用

类外函数使用静态成员对象时,需得更改静态成员变量的私有属性改为公有public属性方可使用

//静态成员变量属于类,因此可以通过类名对它进行访问。访问形式为:
类名::成员变量;

//也可以通过对象名访问,访问形式为:
对象名.静态成员变量;
//编译器通过对象能推出类类型。

引例:上例2、班级系统所有同学作为单独变量,需统计班级某科目总分

//这是配置好的模板文件
#include <iostream>
#include <string>
using namespace std; 

class Stu
{
private:
string name;
string num;
int grade;

public:
static int sum;//静态成员对象的定义
Stu(string na = "XX", string nu="XXXX", int g=90) :name(na), num(nu), grade(g)
{
sum += grade;
};
};
int Stu::sum = 0;//静态成员对象初始化

int main()
{
Stu stu[5]{ {"李华","211",98},{"刘明","212",88},{"王雅","213",66},{"乔伊","214",77},{"曹颖","215",97} };
cout << "总成绩为:" << Stu::sum << endl;//前提静态成员变量为public公有访问权限下,私有错误
cout << "总成绩为:" << stu[0].sum << endl << endl;

Stu stu2{ "陆雅","216",100 };//一改全改
cout << "添加新成绩:100,一改全改:"<<endl;

cout << "总成绩为:" << stu[0].sum << endl;
cout << "总成绩为:" << stu[1].sum << endl;
cout << "总成绩为:" << stu[2].sum << endl;
cout << "总成绩为:" << stu[3].sum << endl;
cout << "总成绩为:" << stu[4].sum << endl;
cout << "总成绩为:" << stu2.sum << endl;
return 0;
}

输出:

静态成员函数

主要是为了处理静态成员数据。

静态成员函数可以在类内定义,也可以在类外定义(静态成员变量只能类内声明,类外定义初始化)

在类外定义时,不加static

在类内声明格式为:

static 返回类型 静态成员函数名(参数表);

通过类名调用

类名::静态成员函数名(实参表); //在类外访问必须是public

通过对象名调用

对象名.静态成员函数名(实参表);//在类外访问必须是public,编译器通过对象能推出类类型。

当调用一个对象的非静态成员函数时,系统会把该对象的起始地址赋予成员函数的this指针。而静态成员函数不属于某一对象,因此它没有this指针。由此可以得出:

静态成员函数不能访问类的非静态成员(包括非静态成员变量和非静态成员函数)。即需要用到this指针的地方静态成员函数是不能访问的。

引例:

#include <iostream>
#include <string>
using namespace std;

class Student //定义Student类
{
private:
    string m_name;    //姓名
    string m_num;        //学号
    float m_score;    //分数
    static float sum; //分数总和
    static int count; //学生总数
public:
    Student(string name,string num, float s) :m_name(name), m_num(num), m_score(s) 
    {
        sum += m_score; //计算总分
        count++;        //累统计总人数
    }
    static float average(); //声明静态成员函数
};

float Student::average() //定义静态成员函数
{
    return(sum / count);
}

float Student::sum = 0; //对静态成员变量初始化
int Student::count = 0; //对静态成员变量初始化

int main()
{
        Stu stu[5]{ {"李华","211",98},{"刘明","212",87},
        {"王雅","213",66},{"乔伊","214",77},{"曹颖","215",97} };
};

    cout << "学生的平均成绩为:" << Student::average() << endl;//调用静态成员函数

    return 0;
}


原文地址:https://blog.csdn.net/weixin_62946182/article/details/135823438

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!