精华内容
下载资源
问答
  • 静态数据成员和静态成员函数

    万次阅读 多人点赞 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。

     

    展开全文
  • C++类的成员函数

    2021-06-08 10:00:48
    类的成员函数是函数的一种,它的用法和作用和一般函数基本上是一样的,它也有返回值和函数类型。它与一般函数的区别只是:它是属于一个类的成员,出现在类体中。它可以被指定为private(私有的),public(公用的)...

    1 C++类的成员函数

    1.1 C++类成员函数的性质

           类的成员函数是函数的一种,它的用法和作用和一般函数基本上是一样的,它也有返回值和函数类型。它与一般函数的区别只是:它是属于一个类的成员,出现在类体中。它可以被指定为private(私有的),public(公用的)或protected(受保护的)。

           在使用类成员函数的时候,要注意调用它的权限(即,它能否被调用)以及它的作用域(函数能使用什么范围中的数据和函数)。例如,私有的成员函数只能被本类中的其他成员函数所调用,而不能被类外调用。成员函数可以访问本类中任何成员(包括私有的和公用的),可以引用在本作用域中有效的数据。

           所以,定义类的成员函数时,可以将需要被外界调用的成员函数指定为public,它们是类的对外接口。但应注意,并非要求把所有成员函数都指定为public。有的函数并不是准备为外界调用的,而是为本类中的成员函数所调用的,就应该将它们指定为private。

           类的成员函数是类体中十分重要的部分,如果一个类中不包含成员函数,就等同于C语言中的结构体类,体现不出类在面向对象程序设计中的作用。

    1.2 在类外定义成员函数

           前面看到的成员函数是在类体中定义的,那么,也可以在类体中只写成员函数的声明,而在类外面进行函数定义,例如:

    class student       //class开头

    {

    private:    //以下的部分是私有部分

        char name[32];

        char addr[32];

        long long number;//以上3 行是成员变量

    public:     //以下部分是公有部分

        student(char* pn, char* pa, long long n)

        {

            strcpy(name, pn);

            strcpy(addr, pa);

            number = n;

        }

        void print();       //这是成员函数

    };

    void student::print()       //这是成员函数

    {

        cout << "name = " << name << endl;

        cout << "addr = " << addr << endl;

        cout << "number = " << number << endl;

    }

           注意:在类体中直接定义函数时,不需要在函数名前面加上类名,因为函数就属于当前定义该函数的类。但成员函数在类外定义的时候,必须在函数名前面加上类名,“::”是作用域限定符或称作用域运算符,用它声明函数是属于哪个类的。

    例如,student::print() 表示作用域为student类的print()函数,也就是student类中的print()函数。如果没有“student::”的限定,print()指的是它所在的作用域中的print()函数,就是一个普通的函数,不属于student类。对上面程序段而言,就是指全局作用域中的print()函数,而不是student类中的print()函数。而且不同的类中可能有同名的函数,用作用域限定符加以限定,就明确地说明了是哪一个作用域的函数,也就是哪一个类的函数。

           如果在作用域运算符“::”的前面没有类名,或者函数名前面既无类名,又无作用域运算符“::”,如:

    ::print()          或          print()

    就表示 print() 函数不属于任何类,这个函数不是成员函数,而是全局函数,即非成员函数的一般普通函数。

           类函数必须先在类体中作原型声明,然后,在类外定义,也就是说类体的位置应在函数定义之前(如上面所示的那样),否则编译时会出错。

           虽然函数在类外部定义,但在调用成员函数时会根据在类中声明的函数原型找到函数的定义(函数代码),从而执行该函数。

    韦凯峰 Linux C/C++ 程序设计教程,Linux 系统编程,Openwrt 系统开发,微信:13926572996,QQ:1523520001,博客:www.mylinux.vip

    展开全文
  • C++的成员函数分为静态函数、非静态函数和虚函数三种,在本系列文章中,多处提到...考虑以下两种函数调用:前者需要传入一个类指针,属于成员函数调用,后者直接指明Animal类的函数调用。本质上,这两个函数是一样的
  • 下列有关静态成员函数的描述中,正确的是: A、静态数据成员可以在类体内初始化 B、静态数据成员可以被类对象调用 C、静态数据成员受private控制符作用 D、静态数据成员可以直接用类名调用答案:DA,静态...

    下列有关静态成员函数的描述中,正确的是:
    A、静态数据成员可以在类体内初始化
    B、静态数据成员不可以被类对象调用
    C、静态数据成员不受private控制符作用
    D、静态数据成员可以直接用类名调用

    答案:D

    A,静态成员属于类,而不是属于某个特定的对象,它是由该类的所有对象共享的,因此不能在类的构造方法中初始化
    B,静态成员属于该类所有对象公有,可以被类对象调用
    C,静态成员收private的限制
    D,静态成员属于类和该类的所有对象,可以用类名直接调用

    展开全文
  • 成员函数的定义

    千次阅读 2020-05-06 17:03:55
    实际上,成员函数和方法指的是同一种实体, 是一种实体的两种不同叫法, 成员函数是程序设计语言 C + + 中的术语,而方法是面向对象方法中的术语。在以后的叙述中, 本书采用术语成员函数。 成员函数的定义通常采用两种...

    成员函数的定义

    如上所述, 类中含有两种成份,即数据成员和成员函数, 其中成员函数也称方法。实际上,成员函数和方法指的是同一种实体, 是一种实体的两种不同叫法, 成员函数是程序设计语言 C + + 中的术语,而方法是面向对象方法中的术语。在以后的叙述中, 本书采用术语成员函数。
    成员函数的定义通常采用两种方式。
    第一种方式是在类声明中只给出成员函数的原型, 而成员函数体在类的外部定义。这种成员函数定义的一般形式是:

    返回类型 类名∷函数名(参数表) {
    // 函数体
    }
    

    例如,表示坐标点的类 point 可声明如下:

    class point
    {
    private :
        int x, y;
    public:
        void setpoint (int, int) ;
        // 设置坐标点的成员函数 setpoint( )的函数原型 int getx( ) ;
        // 取 x 坐标点的成员函数 getx( )的函数原型
        int gety ( ) ;
        // 取 y 坐标点的成员函数 gety( )的函数原型
    } ;
    void point∷setpoint( int a, int b)// 定义成员函数 setpoint( )
    {
        x = a;
        y = b;
    }
    int point∷getx( ) // 定义成员函数 getx( )
    {
        return x;
    }
    int point∷gety( ) // 定义成员函数 gety( )
    {
        return y;
    }
    
    

    从这个例子可以看出,虽然函数 setpoint( )、getx( )和 gety( ) 在类外部定义, 但它们属于类 point 的成员函数, 它们可以直接使用类 point 中的数据成员 x 和 y。

    说明:

    1. 在所定义的成员函数名之前应缀上类名, 在类名和函数名之间应加上分隔符 “∷”,例如上面例子中的“point∷”。
    2. 在定义成员函数时, 对函数所带的参数, 不但要说明它的类型, 还要指出其参 数名。
      3.在定义成员函数时, 其返回类型一定要与函数原型中声明的返回类型匹配。 成员函数的第二种定义方式是:将成员函数定义在类的内部, 即定义为内置函数。在 C + + 中, 可以用下面两种格式定义类的内置函数:

    (1 ) 隐式定义
    所谓内置函数的隐式定义, 就是直接将函数定义在类内部,例如:

    class point
    {
    private :
        int x, y;
    public:
        void setpoint(int a, int b)
        {
            x = a;
            y = b;
        }
        int getx()
        {
            return x;
        }
        int gety ()
        {
            retrun y;
        }
    } ;
    
    

    此时, 函数 setpoint( )、getx( )和 gety( )就是隐含的内置函数。内置函数的调用类似宏指令的扩展,它直接在调用处扩展其代码, 而不进行一般函数的调用操作。
    (2 ) 显式定义
    在定义内置函数时, 为了书写清晰,仍将它放在类定义体外。但为了使它仍然起内置函数的作用, 在函数定义前冠以关键字“inline”, 以此显式地说明这是一个内置函数。例如上面的例子改为显示定义可变成如下形式:

    class point
    {
    private :
        int x, y;
    public:
        void setpoint(int, int) ;
        int getx() ;
        int gety() ;
    };
    inline void point∷setpoint(int a, int b)
    {
        x = a;
        y = b;
    }
    inline int point∷getx()
    {
        return x;
    }
    inline int point∷gety()
    {
        return y;
    }
    
    

    说明:简单的成员函数定义成内置函数可以提高执行的效率, 但如果函数体较长, 将使程序量增加很多。因此,一般对非常简单的函数才声明为内置函数。

    展开全文
  • 成员函数与内联函数

    2019-09-21 19:10:41
    11.关于成员函数特征的下列描述中,______是错误的. 成员函数一定是内联函数 B. 成员函数可以重载 C. 成员函数可以设置缺省参数值 D. 成员函数可以是静态的 [A] [解析] 因为成员函数可以在类体内定义,也...
  • 成员函数和静态成员函数

    千次阅读 2018-03-12 19:35:51
    成员函数具有以下特殊性质 能更新成员变量的值(静态成员变量除外)能调用除了常成员函数以外的成员函数可以用来区分函数重载类的常对象只能访问类的常成员函数 class A{ private: int w, h; publi...
  • 关于静态成员函数

    千次阅读 多人点赞 2017-09-19 14:02:55
    关于静态成员函数 静态成员是受到private限定符的作用的,若用private修改,可外部访问的  static对象如果出现在类中,那么该对象即使从未被使用到,它也会被构造以及析构。而函数中的static对象,如果该函数...
  • static成员函数属于一个类,而属于某个对象,因此能是虚函数。 内联函数,内联在编译时展开,而虚函数是运行时动态绑定。 什么类成员函数必须成为虚函数 当一个类作为基类时,其析构函数必须是虚函数,...
  • 在该例中运算符重载函数operator+作为Complex类中的成员函数。 可能有的读者会提出这样的问题:”+“是双目运算符,为什么在例10.2程序中的重载函数中只有一个参数呢?实际上,运算符重载函数有两个参数,由于重载函...
  • 和静态数据成员一样,静态成员函数是类的一部分,而不是对象的一部分。如果要在类外调用公用的静态成员函数,要用类名和域运算符“∷”。如 Box∷volume( ); 实际上也允许通过对象名调用静态成员函数,如 a....
  • 今天看effective STL第26条条款时,发现自己之前没意识到如下的几点(看来自己的c++基础还是渣渣水平o(╯□╰)o)。...作为类的成员函数这一点在进行重载函数选择时是一个优先的,因此注意某些情况会导
  • C++ 运算符重载:成员、非成员函数重载

    千次阅读 多人点赞 2020-06-19 19:41:34
    C++ 运算符重载运算符重载1、背景2、运算符函数重载的两种形式1、成员函数重载1、定义格式2、非成员函数重载(友元)1、定义格式3、重载原则4、参数和返回值5、成员函数重载1、双目运算符重载1、定义2、调用格式2、...
  • 今天写程序要用到一个计时器,然后需要创建一个新的线程,这个线程是CtestDLG的一个成员函数,必须定义为静态的.但是这个时候就能去访问非静态成员变量了,这里找到一个很好的解决办法: 先上代码: 1.线程函数的定义:...
  • 详解c++中类的六个默认的成员函数

    万次阅读 多人点赞 2016-07-06 13:01:35
    类的6个默认的成员函数包括: 构造函数、析构函数、拷贝构造函数、赋值运算符重载函数、取地址操作符重载、const 修饰的取地址操作符重载。 (一)构造函数 构造函数,顾名思义,为对象分配空间,进行初始化。它是一...
  • c++类成员函数作为回调函数

    万次阅读 多人点赞 2016-06-29 22:44:30
    最近又仔细学了会,感觉回调函数,我认为就是将一个函数指针A作为参数传入另外一个函数B,然后在函数B中调用函数A。  普通回调  具体先看一个简单的例子:   #include void printWelcome(int len) { printf(...
  • 静态数据成员和静态数据成员函数

    千次阅读 多人点赞 2016-12-27 15:25:29
    c++中的static静态数据成员和静态成员函数应该是让大家比较头疼的东西,好像也是找工作公司面试中常常问到的东西。我自己也深有体会,在学习c++的过程中,总感觉static很烦人,但是又是一个必须懂的东西,所以今天就...
  • 在类模板(及其成员函数)的定义中,我们将模板参数当作替身,代替使用模板时用户提供的类型或值。 代码示例: template <typename T> //用T这个模板类型参数,来表示A中保存的元素的类型。 //当用户实例化A...
  • 作者:铿然一叶和静态数据成员一样,静态成员函数是类的一部分,而不是对象的一部分。如果要在类外调用公用的静态成员函数,要用类名和域运算符“∷”。如 Box∷volume( ); 实际上也允许通过对象名调用静态成员函数...
  • 函数指针的初始化 函数如下: int CompareString(const string&amp; str1, const string&amp; str2) { return str1.compare(str2); } 函数的初始化有两种方式: 第一种,也是最普遍的方式: int...
  • Q1:成员函数分为三种:静态成员函数,非静态成员函数,虚拟成员函数。本节的讨论均使用以下的类例子:Eg: class Point3d { public: Point3d(int i = 0, int j = 0, int k = 0) :_x(i), _y(j), _z(k){} Point3d ...
  • 因此可以看出,每个对象占用的存储空间只是该对象的数据部分(虚函数指针和虚基类指针也属于数据部分)所占用的存储空间,而包括成员函数所占用的存储。 测试代码 代码如下,以下代码的输出结果是什么? cl...
  • 为了便于理解,我们先来说说面向过程设计中的static,对理解面向对象设计中的static多少会有些裨益,也可以加深大家对这方面知识的理解。面向过程中设计中的static...静态函数只能在声明它的文件当中可见,能被其他
  • 首先,介绍三种重载方式: 1 //作为成员函数重载(常见) 2 class Person{ 3 Private: 4 string name; 5 int age; 6 public: 7 Person(const char* name, int age):name(name),age(age){} 8 bool operator&...
  • C++类的六个默认成员函数

    千次阅读 2018-08-22 19:30:11
    经过编译器处理之后,类A在为空,它会自动的生成六个默认的成员函数,即使这六个成员函数什么也做。(这些成员函数当我们没有定义时,编译器会显示的调用)处理之后相当于: class A { public: A();//构造...
  • 关于有些运算符只能用成员函数重载

    万次阅读 多人点赞 2018-07-27 10:12:16
    能重载为类的静态成员应该比较容易理解,因为静态成员函数是属于整个类的,不是属于某个对象的,它只能去操作类静态数据成员。而赋值运算符“=”是基于对象操作的。 那么为什么赋值运算符可以重载为类的友元函数...
  • 继承规则及派生类的成员函数

    千次阅读 2018-09-19 16:38:40
    成员访问限定符&amp;继承关系: 这是一个简单的继承关系: #include&lt;iostream&gt; #include&lt;Windows.h&gt; using namespace std; class person { public: char* nam...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 125,214
精华内容 50,085
关键字:

以下不属于成员函数的是