精华内容
下载资源
问答
  • 在类中的某个数据成员前加
    万次阅读 多人点赞
    2017-03-09 10:30:35

    1 静态数据成员不能用参数初始化表对静态数据成员初始化

    (1) 如果声明了类而未定义对象,则类的一般数据成员是不占内存空间的,只有在定义对象时,才为对象的数据成员分配空间。但是静态数据成员不属于某一个对象,在为对象所分配的空间中不包括静态数据成员所占的空间。静态数据成员是在所有对象之外单独开辟空间。只要在类中指定了静态数据成员,即使不定义对象,也为静态数据成员分配空间,它可以被引用。

    (2) 静态数据成员不随对象的建立而分配空间,也不随对象的撤销而释放(一般数据成员是在对象建立时分配空间,在对象撤销时释放)。静态数据成员是在程序编译时被分配空间的,至程序结束时才释放空间

    (3) 静态数据成员可以初始化,但只能在类体外进行初始化

    注意:静态数据成员不能用参数初始化表对其初始化。如在定义Box类中这样定义构造函数是错误的:Box(int h, int w, int len):height(h){}

    (4) 静态数据成员可以通过对象名引用,也可以通过类名引用。

                                     —《C++面向对象程序设计(第2版)》P104-P105

    分析:静态数据成员可以初始化,但只能在类体外初始化,并且不能用参数初始化表对其初始化。

    如: class Box

         {

            public:

               int volume();

           private:

               static int height;

               int width;

               int length

    };

     

    int Box::height = 10; //正确

    Box(inth, int w, int len):height(h){} //错误

     

    静态成员与对象无关,属于整个类,构造函数是构造某个具体的对象。创建一个对象的时候会用到初始化表,但是静态成员在对象创建之前就已经存在了,所以不需要再初始化表中初始化。

    更多相关内容
  • 静态数据成员和静态成员函数

    万次阅读 多人点赞 2018-08-26 19:18:35
    c++的static静态数据成员和静态成员函数应该是让大家比较头疼...我自己也深有体会,学习c++的过程,总感觉static很烦人,但是又是一个必须懂的东西,所以今天就对静态数据成员和静态成员函数坐下小结哈! 一...

    转载自:https://blog.csdn.net/computer_liuyun/article/details/29235111

    c++中的static静态数据成员和静态成员函数应该是让大家比较头疼的东西,好像也是找工作公司面试中常常问到的东西。我自己也深有体会,在学习c++的过程中,总感觉static很烦人,但是又是一个必须懂的东西,所以今天就对静态数据成员和静态成员函数坐下小结哈!

    一、静态数据成员

    1.静态数据成员怎么去定义?

    在类中声明静态数据成员很简单,是以static关键字表明即可,如下所示

    class Test{
    private:
    	//静态数据成员
    	static int a;
    };
    

    a就是静态数据成员了,在类中只能声明可是不能定义哈!

    要对静态数据成员定义和初始化必须在类的外面也就是在全局作用域中定义,如果定义不给出初值,则默认初值为0

    class Test{
    public:
    	int GetA() const{return a;}
    private:
    	//静态数据成员
    	static int a;
    };
    //int Test::a;如果这样定义不赋予初值则初值为零
    int Test::a = 1;
    #include <iostream>
    int main()
    {
    	Test T;
    	std::cout << T.GetA() << std::endl;
    }
    

    定义时一定要在全局作用域中定义,一定不要在类中定义!

    静态数据成员甚至在类没有任何对象的时候都可以访问,静态成员可以独立访问,无需依赖任何对象的建立

    另外,不要试图在头文件中定义(初始化)静态数据成员。在大多数的情况下,这样做会引起重复定义这样的错误。即使加上#ifndef #define #endif或者#pragma once也不行。

     

    2.静态数据成员被类的所有对象共享,包括该类的派生类对象,基类对象和派生类对象共享基类的静态数据成员

    答:静态数据成员不属于任何对象,类的静态数据成员的存在不依赖于任何类对象的存在,静态数据成员是由类的所有对象共享的。例子如下:

    class Base{
    public:
    	//静态数据成员
    	static int a;
    };
    class Derived : public Base{
     
    };
    //int Test::a;如果这样定义不赋予初值则初值为零
    int Base::a;
    #include <iostream>
    int main()
    {
    	Base B;
    	Derived D;
    	B.a++;
    	std::cout << B.a << std::endl;
    	D.a++;
    	std::cout << D.a << std::endl;
    	
    }
    

    打印结果如下:

    由打印结果看出来,派生类对象和基类对象都是共享基类的静态数据成员,而基类的所有对象也是共享该静态数据成员,且该静态数据成员应该在全局作用域中定义,可以赋予初值也可以不赋予初值,如果不赋予初值,静态数据成员有其默认值。

     

    3.静态数据成员可以作为成员函数的默认形参,而普通数据成员则不可以

    答:不多说,直接看例子马上就明白了哈!

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

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

    答:这个也不多说,直接看例子就可以懂什么意思哈!

    class Test{
    public:
    	//静态数据成员
    	static Test a;//正确
    	Test b;//报错
    	Test *pTest;//正确
    	Test &m_Test;//正确
    	static Test *pStaticObject;//正确
    };
    

    5.静态数据成员在const函数中可以修改,而普通的数据成员是万万不能修改的哈!

    答:看个例子

    class Test{
    public:
    	Test():b(0){}
    	//静态数据成员
    	static int a;//正确
    	int b;
    	void test() const
    	{
    		a++;
    		b++;//const指的不能修改当前调用该函数对象的数据成员
    	}
    };
    int Test::a;
    

    const修饰的时当前this指针所指向的对象是const,但是静态数据成员不属于任何类的对象,它被类的所有对象修改,所以this指针不修饰静态的数据成员,所以可以更改。

     

    二、静态成员函数

    静态成员函数的声明也很简单,就是在类的成员函数前加上static关键字即可,和静态成员一样,静态成员函数也是属于类的,它并不属于任何对象,当调用静态成员函数时应该使用类名和域运算符“∷”,当然也可以使用对象调用操作,但是这样的操作并不意味着静态成员函数属于这个对象,它只是被这个对象共享而已,这样也就决定了静态成员函数中是不能访问本类中的非静态数据成员的,它是不能访问非静态数据成员的,在c++中静态成员函数主要用来访问静态数据成员而不访问非静态数据成员

    1.静态成员函数不能调用非静态成员函数,但是反过来是可以的

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

    3.静态成员函数的地址可用普通函数指针储存,而普通成员函数地址需要用 类成员函数指针来储存。

    总结:其实声明为静态,不论是静态数据成员还是静态成员函数,它们都是不依赖于对象而存在的,类在定义后并不分配存储空间,而是在定义类的对象的时候才分配存储空间,相反静态的数据成员和静态的成员函数是已经在内存中开辟了内存空间了,所以静态数据成员可以独立的访问在任何类对象没有建立起来都可以访问,并且静态成员函数不可以调用非静态成员函数,因为非静态成员函数只有在类对象建立以后才可以调用,相反则是可以的。我觉得当对某个判断产生怀疑的时候应该去测试,只有验证了才知道是不是对的哈!

    为了能更好阐释静态数据成员和静态成员函数,然后在网上搜了博客,感觉有些例子不错(因找不到最初的出处,所以无法注明请原作者谅解),所以就拿来给大家参考一下哈!

    关于玩篮球的例子很能明显解释静态数据成员和静态成员函数到底是怎么回事

    你们班里面有10个人(10个比如高一一班的对象),体育老师分给你们一个篮球(静态成员函数),你们每个人都带了一个篮球(非静态成员数),你们都很小气,自己的球只能自己拍,要是5对5打比赛,那就只能用那个静态的篮球了(每个人都可以拿来用,但是带来的影响是对全体的)。因此,我可以说那个篮球是高一一班的成员。所以也就是说:静态成员函数是类的成员函数(因为高一二班就不能拿来玩),但是这个篮球最后还是要还给老师的,任何私人不得占有。希望这样你能明白,其实在内存空间里面说白了静态的成员的内存是唯一的一份,就是当你在类外声明他时开辟的,但是非静态函数的空间分配是在你实例化对象时创建的。

    为了使大家更好的理解这两个概念,还是老样子用代码来说明上面文字说明的这一切哈!

    关于学生类的例子

    //定义Student类
    #include <iostream>
    class Student                  
    {
    public:
    //定义构造函数
    Student(int n,int a,float s):num(n),age(a),score(s){ }      
    void total();
    //声明静态成员函数
    static float average();      
    private:
    	int num;
    	int age;
    	float score;
    	//静态数据成员,累计学生的总分
    	static float sum; 
    	//静态数据成员,累计学生的人数
    	static int count;           
    };
    //在全局作用域对静态数据成员初始化,如果不赋予初值,则使用其默认值零
    float Student::sum;                     
    int Student::count;
    //定义非静态成员函数
    void Student::total()                    
    {
    	//累加总分
    	sum+=score;
    	//累计已统计的人数
    	count++;                               
    }
    //定义静态成员函数
    float  Student::average()                  
    {
    	return(sum/count);
    }
    int main()
    {
    	Student stud[3]={    
    	//定义对象数组并初始化
    	Student(1001,18,70),
    	Student(1002,19,78),
    	Student(1005,20,98)
    };
    int n;
    std::cout<<"please input the number of students: ";
     //输入需要求前面多少名学生的平均成绩
    std::cin>>n;                              
    //调用3次total函数
    for(int i=0;i<n;i++)
    {
    	stud[i].total();
    }
    //调用静态成员函数
    std::cout<<"the average score of "<<n<<" students is "<<Student::average( )<<std::endl;
    return 0;
    }
    

    打印输出如下:

     

    对上面的代码做以下说明:

    首先,在主函数中定义了对象数组,存放每个学生的编号、年龄和成绩,其中sum和count是要累计所有学生的总成绩和总的学生人数,我们定义成了静态数据成员,在学生类的成员函数中,我们定义了普通的total成员函数,用来计算所有学生的总成绩和总的学生人数,另外,定义了静态成员函数average,学生类的设计大概如此

    在全局作用域对类中静态数据成员进行了定义,但未赋予初值,这意味着我们采用其默认值。

    在类的普通成员函数toal中可以引用静态数据成员sum和count,可见类的所有成员函数都可以引用类的静态数据成员。

    在类的静态成员函数average中,只能引用类的静态数据成员,不能引用非静态数据成员。

    在主函数中我们调用类的非静态成员函数时只能通过类对象来调用,如stu[i].total,但是对于静态成员函数可以直接通过类名+作用域符号来调用,如

    Student::average。

     

    展开全文
  • 1.什么是静态成员 静态成员是类的所有对象共享的成员,而不是...静态数据成员在类中只有一个拷贝,不占用对象的存储空间,由该类的所有对象共同维护和使用 3.静态成员函数 如果某个方法为整个类所共有,不属于任何一...

    1.什么是静态成员
    静态成员是类的所有对象共享的成员,而不是某个对象的成员。
    静态成员分为静态数据成员静态成员函数
    2.静态数据成员
    如果某个属性为整个类所共有,不属于任何一个具体对象,则采用static关键字来声明为静态数据成员,例如:银行账户的利率
    静态数据成员在类中只有一个拷贝,不占用对象的存储空间,由该类的所有对象共同维护和使用
    3.静态成员函数
    如果某个方法为整个类所共有,不属于任何一个具体对象,则采用static关键字来声明为静态成员函数
    静态成员函数形参表中没有this指针形参,因此,静态成员函数内不能直接访问this指针

    4.使用方法:
    //student.h
    class Student
    {
    public: Student(); ~Student();
    Student(int pid,char * pname,float s);
    Student(const Student& init);
    void Display();
    static int Number( ); //静态成员函数的声明
    private: int id;
    char * name;
    float score;
    static int total; //静态数据成员的声明,代表班级学生总人数
    };
    //在类体外实现时不要加static关键字,否则错误 且其返回值必须是静态的
    //student.cpp
    int Student::Number()
    {//} //Right
    static int Student::Number()
    {//} //Error

    类内非静态成员函数可以直接访问非静态成员、静态成员;静态成员函数可以直接访问静态成员,通过对象访问非静态成员

    类外访问静态成员受成员访问权限的控制,可以有2种方法:
    (1)采用类外访问非静态成员的方法
    通过对象名、对象指针、对象引用访问公有静态成员
    for example: S1.Number( ) //S1为创建的对象

    (2)采用类名加作用域限定符的方法
    <类名>::<公有静态成员>
    for example: Student::Number( )
    且在类的实现前要进行静态成员的初始化和分配空间,即在cpp中定义类中成员函数前,需给静态成员分配空间和初始化

    静态成员与全局对象的区别
    1.静态成员的名字是在类的作用域中,因此可以避免与其他类的成员或全局对象名字冲突
    可以实施封装。
    2.静态成员可以是私有成员,而全局对象不可以
    3.通过阅读程序容易看出静态成员是与特定类关联的,可以清晰地显示程序员的意图

    展开全文
  • 1.同一内数据的共享 ...因此,如果我实例化的一个对象,其对象本身是不能直接使用"."访问符访问其对象内的私有数据成员的,更不用说同一的其他实例化的对象了。 比如,我们有一个Student,其

    1.同一类内数据的共享

    在面向过程的语言中,我们知道,两个函数之间如果想要“互通有无”发送点数据,其无外乎两种方式,要么是通过一个函数调用另一个函数,调用时传递参数即可;或者是直接大家共享一个全局变量,那么便都可以对此变量进行访问和修改了。C++是一门面对对象的语言,将函数和数据等封装在了类内,其目的是为了解决客观世界的问题而设计。我们知道,类的私有数据成员private只允许其自身的成员函数来访问和修改。因此,如果我实例化类的一个对象,其对象本身是不能直接使用"."访问符访问其对象内的私有数据成员的,更不用说同一类的其他实例化的对象了。

    比如,我们有一个Student类,其类内声明了私有数据成员身高height、体重weight等,我们对Student类实例化两个对象ZhangSanLiSi,那么ZhangSan有张三的数据成员,LiSi有李四的数据成员,他们俩人的数据成员当然是不互通的,肯定是不能共享同一个数据成员的。但如果张三和李四他们两个人之间想要“互通有无”发送点数据呢?比如我们想要统计下学生总数Count,这个数据放在什么地方才可以让同一类的不同对象都可以访问和修改呢?这就是同一类内不同对象之间的数据的共享,也就是我们接下来说的静态数据成员静态成员函数的应用。

    1.1 静态数据成员

    同一类内,不同对象之间的数据成员是在每一个对象中拥有一个复本,这个属性正是每个对象区别于其他对象的特征,现在我们要做的是让这个属性是同一类内所有的对象成员都拥有,大家都可以访问和修改。这就需要采用一个关键字:static,在数据成员的类型定义符之前加上static关键字后,那么此数据成员便成为了同一类的所有对象所共同拥有和维护的属性,从而实现了我们的目的:想要在同一类中不同对象之间实现数据共享

    具体用法为:

    静态数据成员声明:    static 数据类型 变量名;如:static int Count ;

    和一般的数据成员不同的是,静态数据成员在类内声明后,还必须要成员函数一样在类外进行定义(或者说实现)。

    具体用法为:

    静态数据成员实现:    数据类型 类名::变量名 = 初始化值;如:int Student::Count = 0;

    这里需要指出的是,如果定义不给出初值,则默认初值为0

    简单来说其声明和定义的特殊性是:

    1.类内声明(前面加static

    2.类外定义实现(前面无static

    3.不允许通过构造函数初始化列表的形式初始化

    另外,其还有一些之外的特殊属性:

    1.静态数据成员被类的所有对象共享,包括该类的派生类对象,基类对象和派生类对象共享基类的静态数据成员。也就是说,静态数据成员不属于任何对象,类的静态数据成员的存在不依赖于任何类对象的存在,静态数据成员是由类的所有对象共享的。

    2.静态数据成员可以作为成员函数的默认形参,而普通数据成员则不可以。如下例:

    class Student
    {
    public:
    	//静态数据成员
    	static int Count;
    	int number;
    	void showCount(int i = Count);//正确
    	void showCount(int i = number);//报错
    };

    3.静态数据成员的类型可以是所属类的类型,而普通数据成员则不可以。普通数据成员的只能声明为所属类类型的指针或引用。如下例:

    class Student
    {
    public:
    	//静态数据成员
    	static Student count;//正确
    	Test number;//报错
    	Test *pStudent;//正确
    	Test &m_Student;//正确
    	static Student*pStaticObject;//正确
    };

     4.后面我们会讲到,常成员函数const是不能修改目标对象数据成员的,但是在static静态数据成员这里就有所特殊,即静态数据成员在const函数中可以修改,而普通数据成员则是不能修改的。

    总结完以上其特殊性,我们通过以上方法,便得到了一个类似于在该类内是全局变量的特殊数据成员—静态数据成员。该数据成员在类内实例化的每个对象都可访问和修改,但是如果想访问,我们必须得有个该类实例化后的对象,再通过该对象的某个成员函数访问此数据成员,这就给我们造成了不变,由于Count是整个类共有的,不属于任何对象的,因此我们自然不希望再实例化一个对象后再访问Count,我们能不能直接通过类名来引用类内某一函数来访问此成员呢?故在设计中引入了接下来的静态成员函数的概念。

    1.2 静态成员函数

    所谓静态成员函数,和前面的静态数据成员类似,是加了static关键字的成员函数。那么,类内的静态成员函数和类内的普通成员函数有什么不一样的呢?

    首先其声明形式:

    静态成员函数的声明:          static 返回值类型 函数名(形参);如:static void showCount();

    其实现形式:

    静态成员函数的实现:          返回值类型  函数名(形参);如:void showCount();

    其声明和实现形式的特殊性还是总结如下:

    简单来说其声明和定义的特殊性是:

    1.类内声明(前面加static

    2.类内类外都可定义实现(类外前面无static,不同于静态数据成员,其可在类内以内联函数的形式实现

     其属性的特殊性是:

    1.静态成员函数不能调用非静态成员函数,但是反过来是可以的。

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

    3.静态成员函数的地址可用普通函数指针储存,而普通成员函数地址需要用 类成员函数指针来储存。

    通过以上方法,我们便可直接通过类名::静态成员函数名来直接调用静态成员函数了,不必再进行对象的实例化。如我们可:Student::showCount();基于此语句,我们没对对象实例化,便访问或者输出了静态数据成员count

    至此,依靠静态数据成员和静态成员函数,我们便实现了同一类内不同对象之间信息传递。


    2.不同类或对象之间数据的共享

    解决了同一类内不同对象之间数据的共享问题,我们接下来要解决的就是类和对象的成员函数之间、不同类与类之间数据的共享问题。不同的类别群体之间共享一些信息在客观世界中也是经常存在的,比如现在有两个类:ZhangSan张三类、LiSi李四类。张三和李四是邻居,张三有几条狗小三红,小三绿,小三蓝(成员函数),李四也有几条狗小四红,小四绿,小四蓝(成员函数),大家各自都有好几盆珍贵的狗粮(私有数据成员),以前呢,张三和李四只能是自家狗吃自家的狗粮(对应各自类内成员函数访问私有数据成员),后来张三和李四成为了好朋友,他们的狗可以互相吃对方的狗粮,这就是两个类之间信息的共享。C++作为一门面向对象的语言,当然也是有相应的操作来抽象和处理这种状况。

    2.1 不同"类"和"对象的成员函数"之间数据的共享

    不同类和对象的成员函数之间数据的共享是依靠友元函数来实现的,所谓友元函数,其就是在类的定义中用关键词“friend”来修饰声明的一种非(该类的)成员函数。友元函数可以是一种普通的函数,也可以是其他类的成员函数。

    还是张三和李四的例子,某天张三出门遇到大蟒蛇,是李四的狗小四蓝和大蟒蛇搏斗救了张三,张三便认定了李四的狗小四蓝是他的好朋友,允许小四蓝可以随便吃他家的狗粮,这就是张三类声明了李四类的成员函数是其友元函数,那么友元函数就可以像其类自身的成员函数一样通过对象名来访问类的私有和保护成员了。

    其声明形式如下:

    友元函数声明:friend 函数返回值类型 函数名(形参表); 如:friend void dogFourBlue();

     要注意的是:

    1.友元函数的声明:因友元函数因为不是类内部的函数,因此其声明不受访问限制符的影响。这句话的意思是:友元函数只需要在类内声明即可,而不需要考虑在public内还是private内声明。

    2.友元函数的定义(实现):因为不是类内的成员函数,其实现也理所应当的在类外实现,准确点说,其实现与类根本无关。

    通过引用友元函数fried,我们便解决了类和其他函数之间信息共享的问题,其friend性质也符合客观实际,很好理解。友元函数的关键所在,即友元函数可以通过对象名直接访问类内的私有数据成员

    2.2 不同"类"之间数据的共享

    上面我们解决了不同类和对象的成员函数之间信息的共享,那么不同类和类之间信息的共享如何实现呢?同友元函数一样,我们只需要在类内声明哪个类是我的友元类即可。

    其声明形式如下:

    友元类声明:friend class 类名;   如:friend class LiSi;

    如上所示,某天张三又出门遇到了大蟒蛇,这次是李四救了他,因此他声明:LiSi类为ZhangSan类的友元类friend,那么此时:LiSi类的所有成员函数(所有狗)都是ZhangSan类的友元函数,都可以访问ZhangSan类的私有和保护成员(都可以吃狗粮)。

    为类声明了友元类,其便建立了类与类之间的联系,这是实现类之间数据共享的一种途径。

    2.3 友元关系的说明

    上面我们介绍了两种友元关系:友元函数和友元类。关于友元关系,还有几点需要注意:

    1.友元关系是不能传播的,比如李四是张三的朋友,王五是李四的朋友,如果没有声明,不能认定张三和王五是朋友,也就不能进行数据的共享。

    2.友元关系是单向的,这个很好理解,张三因为李四救了他,一厢情愿认为李四是他张三的好朋友,可以让李四的所有狗都可以吃他的狗粮。但李四可不一定这么认为,李四如果不认为张三是其好朋友,那么张三的狗就不能吃李四家的狗粮,而只能李四家的狗可以吃张三家的狗粮,即单向关系。

    3.友元关系也不能继承,张三认为李四是其朋友,允许李四家的狗吃其狗粮,但不见得认为李四的孩子也是其朋友,没有声明,当然不会允许李四其孩子家的狗也来吃狗粮。

    3.共享数据的保护

    前面我们讲的是数据的共享在类或对象中的体现,我们知道,共享数据其实是在一定程度上破坏了数据的安全性,本来类封装私有数据成员只能其自身的成员函数访问和修改,现在其他人也可以了,这本身是对数据隐蔽性的一种破坏。那可不可以我允许和你共享,但是不允许你修改呢?一个常见的例子就是去图书馆借书,允许你看,不允许你更改涂抹。在C++中,为了有效的保护数据,因此也引入了类的常对象、类的常成员(包括常成员函数和常数据成员)、常引用这三个概念。

    3.1 常对象

    常对象顾名思义就是在实例化一个新对象时,加上关键字const,设置其为常对象。

    其形式为:

    常对象语法形式:const 类型说明符 对象名(形参);  如,const Student  A(3,4);

     这样,整个对象A就变为了常对象。

    总结常对象有以下特性:

    1.常对象必须在刚开始实例化时就初始化。因为其数据成员在对象的整个生存期间内都是不允许修改的,故我们必须在刚开始就对其进行初始化,之后就固定不变了无法更新。

    2.常对象无法调用普通成员函数。因为调用普通成员函数是可以修改私有数据成员的,这就违背了常对象设计的初衷,因此,直接禁止常对象调用普通成员函数便保证了数据成员不被更改。事实上,常对象只能调用常成员函数,如下面所述。

    3.2 常成员函数

    常成员函数并非有多么特殊,顾名思义,其首先是类的成员函数,其次才是类的常成员函数,因此其和普通的成员函数一样:即可在类内声明,类外定义实现;也可在类内直接定义实现。不同的是,其声明和实现都需要在后面加上一个关键字const

    声明形式:

    常成员函数声明形式:返回值类型说明符  函数名(形参表)const;如:void showCount() const;

     我们前面说了,常对象不允许调用普通成员函数,因为普通成员函数可以修改数据成员,而无法实现我们想要的对数据进行保护,但常对象可以访问常成员函数,怎么保证常成员函数不修改数据成员呢?

    因此,我们直接规定了:

                         常成员函数可以访问但不能更新目的对象数据成员,从而保证了数据成员不被修改。

    但有一个例外需要记住:类内的static静态数据成员,允许常成员函数更改。

    3.2 常数据成员

    有了常对象、常成员函数,当然也要有常数据成员。常数据成员就是用const关键字修饰的类的数据成员变量,仅此而已,并没有什么特殊。

    我们知道对于普通的变量如int,double我们也可以加上const使之变为符号常量,在定义时候就必须进行初始化,其后便不允许更改了,常数据成员也是这样,只不过其初始化方式是通过构造函数的初始化列表罢了。

    其声明形式:

    常数据成员声明:const 类型说明符 变量名;如:const int A;

    其初始化方式:

    常数据成员初始化:通过构造函数初始化列表初始化赋值。如:Student::Student(int number):A(number){}

    #对比静态数据成员和常数据成员:

    在此文里,针对数据成员,我们讲了两种方式:

    1:加static关键字变为静态数据成员,其必须类内声明,必须类外定义,且不允许通过初始化列表进行初始化。

    2:加const关键字变为常数据成员,其是在类内声明,无需额外定义,且必须通过初始化列表的方式进行初始化。

    static静态数据成员相当于是类内的一个全局变量,使得同一类的不同对象之间可以共享同一个数据成员,相当于是提升了其“作用域”。对比发现,const限定的只是限定常数据成员其运行期间不允许被修改,而对其“作用域”没任何作用。事实上,两者根本不冲突也不是一回事,一个相当于属性限定类内大家都可以访问了,一个是属性限定大家都不可以修改,因此常常组合使用,如下所示:

    静态 常 数据成员声明:static const int B; (类内声明,加static关键字)

    静态 常 数据成员实现:const int B = 10; (类外定义,无需static关键字)

    静态常数据成员的意义:允许类内不同对象都可以访问,但一旦初始化后便不再允许修改。

    展开全文
  • 在C++,类的静态成员(static member)必须在类内声明,在类外初始化,像下面这样。 class A { private: static int count ; // 类内声明 }; int A::count = 0 ; // 类外初始化,不必再static关键字 为...
  • C++类中定义数据成员的类型的几种方式
  • C++——的静态成员

    千次阅读 2018-09-03 16:04:20
    一、声明静态成员 ...2、的静态成员存在于任何对象之外,对象不包含任何与静态数据成员有关的数据,静态数据成员被所有该类型的对象共享。 3、静态成员函数也不与任何对象绑定一起,它们不包...
  • 【C++】类中静态成员的声明、初始化类中静态成员的声明初始化静态数据成员值的改变完整例子 有参考大佬 零点零一 的文章:https://blog.csdn.net/thanklife/article/details/78476737 类中静态成员的声明 类中的静态...
  • 函数setDay(),局部变量定义为day时,函数内赋值时要使用this指针已区分两个day变量;或者局部变量定义为与成员变量不同的名字; 1 #include 2 using namespace std; 3 class Data 4 { 5 private: ...
  • 对于C++类中数据成员类型时,定义为对象还是定义为指针,用哪种方法,并没有绝对的情况,需要根据具体情况具体分析。本质上是对象分配区域的问题,前者是栈(stack)上分配空间,后者是堆(heap)上分配空间。...
  • 静态数据成员的定义及初始化

    千次阅读 2017-11-16 11:25:30
    静态数据成员的定义及初始化
  • C++类中的静态数据成员的初始化

    千次阅读 2016-05-16 14:49:24
    每个类只有一个存储单元,静态数据成员为该类的所有对象共有,不属于某个对象。静态数据成员的初始化必须在类以外进行定义性说明。 形式为: :: =值 静态成员注意以下几点: 1、静态成员必须初始化,如果其...
  • 1、const 数据成员不能在类内定义时初始化,在类外初始化也不行。通常通过构造函数初始化。 2、static 数据成员不能在类内初始化,在类外初始化。因为static成员不属于任何一个对象。 3、static const ...
  • 为什么static数据成员一定要在类外初始化?

    万次阅读 多人点赞 2016-09-21 00:30:50
    在C++,类的静态成员(static member)必须在类内声明,在类外初始化,像下面这样。class A { private: static int count ; // 类内声明 };int A::count = 0 ; // 类外初始化,不必再static关键字为什么?...
  • static成员必须在类外初始化

    千次阅读 2017-11-30 21:01:10
    为什么静态成员不能在类内初始化在C++,类的静态成员(static member)必须在类内声明,在类外初始化,像下面这样 class A { private: static int count ; // 类内声明 };int A::count = 0 ; // 类外初始化,...
  • C++类中的静态数据成员--static

    千次阅读 2014-09-08 17:32:10
    使用静态成员的目的是为了解决数据共享的的问题。
  • 数据结构:八大数据结构分类

    万次阅读 多人点赞 2018-09-05 18:23:28
    数据结构分类 数据结构是指相互之间存在着一种或多种关系的数据元素的集合和该集合...数组是可以再内存连续存储多个元素的结构,内存的分配也是连续的,数组的元素通过数组下标进行访问,数组下标从0开始...
  • C#第3讲:、对象和的主要成员

    千次阅读 多人点赞 2018-08-13 15:27:59
    c#是一个面向对象的语言,就是对现实世界某个事物的抽象,比如“人”他程序就可以用一个来表示,人有年龄(Age),有姓名(Name),人还可以吃饭(Eat)和睡觉(Sleep),根据这几点我们就可以创建一个来...
  • 静态数据成员: 就是说这个类中是固定的,只有一个。比如说中国人是一个,那么这个中国人的总人口数就是一个静态数据成员,这个静态数据成员不会跟随某个具体的人,而是正对于这个的。静态成员函数,一般这些...
  • 静态数据成员和静态数据成员函数

    千次阅读 多人点赞 2016-12-27 15:25:29
    c++的static静态数据成员和静态成员函数应该是让大家比较头疼的东西,好像也是找工作公司面试常常问到的东西。我自己也深有体会,在学习c++的过程,...在类中声明静态数据成员很简单,是以static关键字表明即可,
  • 判断Redis有序集合是否存在某个成员的方法 方法一 有序集合,redis没有命令直接判断有序集合是否存在某个成员,但可以借助ZLEXCOUNT命令实现:http://redis.cn/commands/zlexcount.html ZLEXCOUNT key min ...
  • C/C++面试:static修饰类成员函数

    千次阅读 2018-07-24 14:03:58
    我们知道函数内部定义的变量,当程序执行到它的定义处时,编译器为它栈上分配空间,函数栈上分配的空间此函数执行结束时会释放掉,这样就产生了一个问题: 如果想将函数此变量的值保存至下一次调用时,如何...
  • C++和对象(下)——初始化列表、static成员和友元

    千次阅读 多人点赞 2021-03-08 09:23:18
    C++和对象——初始化列表、static成员和友元一、再谈构造函数1.1 构造函数整体...创建对象时,编译器通过调用构造函数,给对象各个成员变量一个合适的初始值。例如我们之前创建的Date class Date { public: D
  • C++的静态变量成员与静态成员函数 ...静态成员变量必须在类外所定义,定义时不能添加static关键字 静态成员函数没有默认的this指针,因为它里面不能使用任何非静态成员 静态成员和普通的类成员...
  • 所以不能在类声明初始化 const 数据成员,因为类的对象未被创建时,编译器不知道const 数据成员的值是什么。  const 数据成员的初始化只能在类的构造函数的初始化表进行。要想建立在整个类中都恒定的常量,应
  • C++类中数据成员类型时,定义为对象还是定义为指针? http://www.cppblog.com/aurain/archive/2012/11/18/195327.html C++,ClassTest objTest;就已经构造了对象,分配了空间;而C#,JavaClassTest...
  • 的静态成员函数和静态数据成员

    千次阅读 2015-10-10 21:31:27
    一、基本知识当将某个数据成员声明为static时,该静态数据成员只能被定义一次,而且要被同类的所有对象共享。各个对象都拥有类中每一个普通数据成员的副本,但静态数据成员只有一个实例存在,与定义了多少对象...
  •  new Book("数据结构与算法(c语言)",38),  new Book("Java程序设计 实例操作",59.8)};  System.out.println("图书总数为:"+ Book.HAOMA());  for(Book b:books){  System.out.println(b.toString());  }  ...
  • 使用C++编程的过程当中,常常需要对类成员进行初始化,通常的方法有两种:第一种方法:CMYClass::CSomeClass() { x=0; y=1; }第二种方法:CSomeClass::CSomeClass() : x(0), y(1) { }本文将要探讨这两种方法的...
  • 在类中只能声明,不能定义 注意在类的内部只是声明,不是定义 类的静态变量是属于类的,不属于某个对象!不能在定义对象时对变量初始化!就时不能用构造函数来初始化!而且使用时应加上类名,而不是对象。例如:...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 494,899
精华内容 197,959
关键字:

在类中的某个数据成员前加