精华内容
下载资源
问答
  • C++类中定义数据成员的类型的几种方式

    时间:2014.04.04

    地点:基地二楼

    —————————————————————

    一、简述

    C++中除了在类中简单声明数据成员外,还可创建static数据成员,const成员,引用成员,const引用等。

    —————————————————————

    二、.静态数据成员

     应用背景:有时没必要让所有类的对象都包含某个变量的副本,或者说你需要一个只对类有意义的数据成员,而不适用于针对某个对象。比如设计一个电子表格的类,每个电子表格都有一个唯一的ID,我们可以为类设计一个从0开始的计数器,这样每个对象可从这个计数器得到自身的ID,但显然没必要为每个对象包含这个计数器,这样的麻烦是因为你还得让计数器保持同步。解决的办法是使用静态数据成员。静态数据成员属于类,而不具体属于类的某个实例,可将静态数据成员当做属于类的全局变量,所有该类的实例对象都只有和可见这么一份。比如:

    class MyClass
    {
        //......
       protected:
          static int counter_=0;
    }
    注意:在C++11中是可以在类的定义中初始化静态成员的。下面介绍具体的两个用法

    1.在类的方法内访问静态数据成员

    在类的方法内部可像使用普通数据成员一样使用静态数据成员。比如:

    类的声明部分:

    class MyClass
    {
      public:
        //.....
        int get_id() const;
      protected:
        //.....
        static int count=0;
        int id_;
    };

    类的实现部分:

    MyClass::MyClass(int in_width,int int height):
    width_(in_width),height_(height)
    {
      id_=count++;
       //......
    }
    也就是说在构造函数中可以访问静态数据成员counter就像访问普通数据成员一样。

    2.在方法外访问静态数据成员

    访问控制限定符也适用于静态数据成员。上面的counter是protected的,因此不能在类外访问,若是公有的则可,具体也是用作用域解析运算符指出这个变量是类的一部分,例如:

    int i=MyClass::count;
    当然,并不建议这么用,而是为类提供get/set方法来授权访问权限。如果想要访问静态数据成员,应该提供静态的get/set方法。

    —————————————————————

    三、常量数据成员

      类的数据成员还可以声明为cosnt,这意味着在创建并初始化之后数据成员的值不能再改变。然而在对象层次上常量通常没有意义,因此常量数据成员通常也是静态的。如果某个常量只适用于类,应该使用静态常量数据成员而不是全局常量。例如设计一个表格类时,我们可能会指定表格表格的最大高度和宽度,这个值可设置成一个静态常量数据成员,当用户想要创建的表格高度或宽度大于该最大值时使用最大值,代码片段如下:

    class SpreedSheet
    {
      public:
         //......
         static const int kMaxHeight=100;
         static const int kMaxWidth=100;
    };
    为什么说在对象层次上常量通常没有意义呢,私下认为,对象本身就是个变量,但对象里面却包含常量很不可思议,是不?换句话说:变得东西里含有不变的成分,那么不变的那部分还有什么意义呢。

    有了上述类中的静态常量,我们就可以在类的构造函数中这样使用这个新的常量了。

    SpreedSheet::SpreadSheet(int width,int hegiy):
      width_(width<kMaxWidth?width:kMaxWidth),
      height(height<kMaxHeight?height:kMaxHight)
    {
      id_=count++;
       //......
    }
    这样当输入宽度或高度大于最大值时,会自动使用最大高度和宽度构造对象。由于kMaxHeight以及kMaxWith是公有的,因此可在程序的任何位置对其进行访问。但必须带作用域解析符,以说明该变量是哪个类的一部分。例:

    cout<<SpreadSheet::kMaxHeight<<endl;

    —————————————————————

    四、引用数据成员

      考虑一个架构问题:电子表格如何与应用程序通信?至少我们应该让应用程序存储电子表格,电子表格也该存储应用程序对象的引用。即具体来说SpreadSheet类必须知道SpreadSheetApplication类,SpreadsheetApplication类也必须知道SpreadSheet类,即通信是双方的,必须相互认识才能有效传递消息么。那么这里就存在一个问题,我们在类的实现里需要相互#inlcude,这就是传说中的循环引用问题,相互#include是不能解决问题的。解决方案是在其中一个头文件中使用前置声明。比如下面含前置声明的类的定义:

    class SpreadsheetApplication;  //前置声明
    classSpreadsheet
    {
      public:
          Spreadsheet(int in_width,Int in_height,SpreadsheetApplication& the_app);
           //......
      protected:
          //......
          SpreadsheetApplication& the_app_;
    };
    这里类的定义将一个SpreadsheetApplicatin引用作为数据成员添加进来,建议使用引用,因为引用总是引用一个SpreadsheetApplication,而指针无法保证这点。在类的构造函数中,每个Spreeadsheet都得到一个应用程序的引用。若不引用某些事物,引用将无法存在,因此在构造函数中必须给the_app_一个值。

    Spreadsheet::Spreadsheet(int in_width,int in_height,SpreadsheetApplication & the_app):
    widthe_(in_width<kMaxWidth?in_width:kMaxWidth),
    height_(in_height<kMaxHeight?in_height:kMaxHight),the_app_(the_app){}
    
    也就是说类中的引用数据成员必须在类的所以构造函数中初始化它。包括复制构造函数:

    Spreeadsheet::Spreadsheet(const Spreadsheet& src):
                                the_app_(src.the_app_){}

    在初始化一个引用之后,不能改变它的引用对象。因此无需在赋值运算符中对引用赋值。

    —————————————————————

    五、常量引用数据成员

      和普通引用可以引用常量对象一样,引用成员也可以引用常量对象。可以这么看,常量不过是普通的一个特殊而已。例如:

    class Spreadsheet
    {
      public:
        Spreadsheet(int in_width,int in_height,const SpreadsheetApplication& the_app);
        //......
      protected:
        //......
      const SpreadsheetApplication& the_app_;
    };
    常量引用和非常量引用的一个重要区别是:比如这里的常量引用SpreadsheetApplication的数据成员 the_app_只能调用SpreadsheetApplication对象上的常量方法。如果试图通过常量引用调用非常量方法,编译报错。







    展开全文
  • 1 静态数据成员不能用参数初始化表对静态数据成员初始化 (1) 如果声明了类而未定义对象,则类的一般数据成员是不...只要在类中指定了静态数据成员,即使不定义对象,也为静态数据成员分配空间,它可以被引用。 (2)

    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){} //错误

     

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

    展开全文
  • C++类中的静态数据成员的初始化

    千次阅读 2016-05-16 14:49:24
    每个类只有一个存储单元,静态数据成员为该类的所有对象共有,不属于某个对象。静态数据成员的初始化必须在类以外进行定义性说明。 形式为: :: =值 静态成员注意以下几点: 1、静态成员必须初始化,如果其...

    每个类只有一个存储单元,静态数据成员为该类的所有对象共有,不属于某个对象。静态数据成员的初始化必须在类以外进行定义性说明。

    形式为:<类型> <类名>::<静态数据成员> =值


    静态成员注意以下几点:

    1、静态成员必须初始化,如果其是有公共访问属性的可以通过对象重新设置值,其最终值以最后一次设置的为准。

    2、初始化方式只能是在类以外进行定义性说明

    3、访问方式可以是对象.静态成员或ClassName::静态数据成员


    通过下面的例子来理解定义:

    1. 包含静态数据成员的类定义头文件代码如下

    #ifndef SINGLETON_H
    #define SINGLETON_H
    
    #include <QObject>
    #include <QString>
    #include <QDebug>
    
    
    class Singleton
    {
    private:
        static Singleton *Instance;
        QString _name;
    
    public:
        static int Test;
    
        static Singleton *createInstance(){
            if(Instance == NULL){
                Instance = new Singleton;
            }
    
            return Instance;
        }
    
        void setName(QString name){
            _name = name;
        }
    
        QString getName(){
            return _name;
        }
    
    private:
        Singleton(){
            qDebug() << "construct";
            Test = 1;
        }
    };
    
    #endif // SINGLETON_H
    

    2. 对应的Cpp文件代码

    #include "singleton.h"
    
    int Singleton::Test = 1;  // 对静态数据成员的初始化操作要在类外进行
    Singleton* Singleton::Instance = NULL;
    

    3. 使用对应的含有静态数据成员的类代码

        Singleton *S1 = Singleton::createInstance();
        Singleton *S2 = Singleton::createInstance();
        Singleton *S3 = Singleton::createInstance();
        Singleton *S4 = Singleton::createInstance();


    展开全文
  • 的静态成员函数和静态数据成员

    千次阅读 2015-10-10 21:31:27
    一、基本知识当将某个数据成员声明为static时,该静态数据成员只能被定义一次,而且要被同类的所有对象共享。各个对象都拥有类中每一个普通数据成员的副本,但静态数据成员只有一个实例存在,与定义了多少对象...

    一、基本知识

    当将类的某个数据成员声明为static时,该静态数据成员只能被定义一次,而且要被同类的所有对象共享。各个对象都拥有类中每一个普通数据成员的副本,但静态数据成员只有一个实例存在,与定义了多少类对象无关。静态方法就是与该类相关的,是类的一种行为,而不是与该类的实例对象相关。

    静态数据成员的用途之一是统计有多少个对象实际存在。

    静态数据成员不能在类中初始化,实际上类定义只是在描述对象的蓝图,在其中指定初值是不允许的。也不能在类的构造函数中初始化该成员,因为静态数据成员为类的各个对象共享,否则每次创建一个类的对象则静态数据成员都要被重新初始化。

    静态成员不可在类体内进行赋值,因为它是被所有该类的对象所共享的。你在一个对象里给它赋值,其他对象里的该成员也会发生变化。为了避免混乱,所以不可在类体内进行赋值。

    静态成员的值对所有的对象是一样的。静态成员可以被初始化,但只能在类体外进行初始化。

    一般形式:

        数据类型  类名::静态数据成员名=初值

    注意:不能用参数初始化表对静态成员初始化。一般系统缺省初始为0。

    静态成员是类所有的对象的共享的成员,而不是某个对象的成员。它在对象中不占用存储空间,这个属性为整个类所共有,不属于任何一个具体对象。所以静态成员不能在类的内部初始化,比如声明一个学生类,其中一个成员为学生总数,则这个变量就应当声明为静态变量,应该根据实际需求来设置成员变量。

    #include <iostream>
    
    using namespace std;
    class test
    {
    private:
        int x;
        int y;
    public:
        static int num;
        static int GetNum()
        {
            //x += 5; //错误,静态成员函数不能调用非静态数据成员,要通过类的对象来调用。
            num += 15;
            return num;
        }
    };
    int test::num = 10;//在类体外对静态数据成员初始化
    int main()
    {
        test a;
        cout<<test::num<<endl;//10
        test::num = 20;//在类体外对静态数据成员再次赋值
        cout<<test::num<<endl;//20
        cout<<test::GetNum()<<endl;//35
        cout<<a.GetNum()<<endl;//50
        return 0;
    }
    

    通过上例可知:

    x+=5;   // 这行代码是错误的
    静态函数成员必须通过对象名来访问非静态数据成员。
    另外,静态成员函数在类外实现时候无须加static关键字,否则是错误的。

    若在类的体外来实现上述的那个静态成员函数,不能加static关键字,这样写就可以了:

      int test::Getnum()
      {
          .........
      }

    1、static成员的所有者是类本身和对象,但是多有对象拥有一样的静态成员。从而在定义对象是不能通过构造函数对其进行初始化。
    2、静态成员不能在类定义里边初始化,只能在class body外初始化。
    3、静态成员仍然遵循public,private,protected访问准则。
    4、静态成员函数没有this指针,它不能返回非静态成员,因为除了对象会调用它外,类本身也可以调用。
    5、静态成员函数可以直接访问该类的静态数据和函数成员,而访问非静态数据成员必须通过参数传递的方式得到一个对象名,然后通过对象名来访问。
    6、设定了静态成员变量,必须要为其赋初值。

    二、静态成员函数访问非静态成员

    类的静态成员(变量和方法)属于类本身,在类加载的时候就会分配内存,可以通过类名直接去访问;非静态成员(变量和方法)属于类的对象,所以只有在类的对象产生(创建类的实例)时才会分配内存,然后通过类的对象(实例)去访问。

    在一个类的静态成员中去访问其非静态成员之所以会出错,是因为在类的非静态成员不存在的时候类的静态成员就已经存在了,访问一个内存中不存在的东西当然会出错。

    C++会区分两种类型的成员函数:静态成员函数和非静态成员函数。这两者之间的一个重大区别是,静态成员函数不接受隐含的this自变量。所以,它就无法访问自己类的非静态成员。

    例1:

    #include <iostream>
    
    using namespace std;
    class test
    {
    private:
        int x;
        int y;
    public:
        static int GetX()
        {
            //x += 5; //错误,静态成员函数不能调用非静态数据成员,要通过类的对象来调用。
            test *p = new test;// new一个类的对象!!!!
            p->x = 222;//使用类的对象调用非静态数据成员!!!!
            p->func();//使用类的对象调用非静态成员函数!!!!
            return p->x;
            delete p;//使用完后delete!!!!
        }
        void func(){cout<<"func()被静态成员函数调用"<<endl;}
    };
    int main()
    {
        test a;
    
        cout<<a.GetX()<<endl;
    
        return 0;
    }
    

    结果:

    func()被静态成员函数调用
    222
    
    Process returned 0 (0x0)   execution time : 0.212 s
    Press any key to continue.

    例2:

    #include <iostream>
    using namespace std;
    
    class M
    {
    public:
         M(int a) {A = a; B += a;}
         ~M(){}
         static void f1();
    private:
         int A;
         static int B;
    };
    
    void M::f1()
    {
         M m(5); //定义并初始化类对象
         cout<<"A="<<m.A<<endl; //静态成员函数中通过对象来引用非静态成员
         cout<<"B="<<B<<endl;
    }
    int M::B=5; //静态数据成员初始化的格式<数据类型><类名>::<静态数据成员名>=<值>
    
    int main()
    {
         M::f1(); //静态成员函数调用时不用对象名
         return 0;
    }
    

    结果:

    A=5
    B=10
    
    Process returned 0 (0x0)   execution time : 0.273 s
    Press any key to continue.

    三、访问私有静态成员数据

    如果把静态成员数据设为私有,可以通过公有静态成员函数!!!!!访问。

    #include <iostream>
    
    using namespace std;
    
    class Cat
    {
    public:
        Cat(int age):itsAge(age){HowManyCats++;}
        virtual ~Cat(){HowManyCats--;}
        virtual int getAge(){return itsAge;}
        virtual void setAge(int age){itsAge=age;};
        static int getHowMany()
        {//公有静态成员函数!!!!!!!!
            return HowManyCats;//访问私有静态成员数据!!!!!
        }
    private:
        int itsAge;
        static int HowManyCats;
    };
    int Cat::HowManyCats=0; //对静态成员数据如此赋值
    int main()
    {
        const int maxCats =5;
        Cat *catHouse[maxCats];
    
        for(int i=0; i<maxCats; i++)
            catHouse[i]=new Cat(i);
        for(int i=0; i<maxCats; i++)
        {
            cout<<"there are "<<Cat::getHowMany();//公有静态成员函数!!!
            cout<<" cats left!"<<endl;
            if(!Cat::getHowMany()) break;
            cout<<"delete the cat which is "<<catHouse[i]->getAge()<<" years old."<<endl;
            delete catHouse[i];
            catHouse[i] = 0;
        }
        return 0;
    }

    结果:

    there are 5 cats left!
    delete the cat which is 0 years old.
    there are 4 cats left!
    delete the cat which is 1 years old.
    there are 3 cats left!
    delete the cat which is 2 years old.
    there are 2 cats left!
    delete the cat which is 3 years old.
    there are 1 cats left!
    delete the cat which is 4 years old.
    
    Process returned 0 (0x0)   execution time : 0.409 s
    Press any key to continue.
    展开全文
  • 在C++,类的静态成员(static member)必须在类内声明,在类外初始化,像下面这样。 class A { private: static int count ; // 类内声明 }; int A::count = 0 ; // 类外初始化,不必再static关键字 为...
  • 对于C++类中数据成员类型时,定义为对象还是定义为指针,用哪种方法,并没有绝对的情况,需要根据具体情况具体分析。本质上是对象分配区域的问题,前者是栈(stack)上分配空间,后者是堆(heap)上分配空间。...
  • 情况一:无get,set,无<< >>重载函数的情况下如何将对象的各个数据成员写入某个文件(提示:可以print函数写代码)。 情况二:当程序包含get,set函数而无<< >>重载函数时,如何将对象的数据成员写入文件...
  • 静态数据成员和静态数据成员函数

    千次阅读 多人点赞 2016-12-27 15:25:29
    c++的static静态数据成员和静态成员函数应该是让大家比较头疼的东西,好像也是找工作公司面试常常问到的东西。我自己也深有体会,在学习c++的过程,...在类中声明静态数据成员很简单,是以static关键字表明即可,
  • 在类中只能声明,不能定义 注意在类的内部只是声明,不是定义 类的静态变量是属于类的,不属于某个对象!不能在定义对象时对变量初始化!就时不能用构造函数来初始化!而且使用时应加上类名,而不是对象。例如:...
  • 1.什么是静态成员 静态成员是类的所有对象共享的成员,而不是...静态数据成员在类中只有一个拷贝,不占用对象的存储空间,由该类的所有对象共同维护和使用 3.静态成员函数 如果某个方法为整个类所共有,不属于任何一...
  • C++类中的静态数据成员--static

    千次阅读 2014-09-08 17:32:10
    使用静态成员的目的是为了解决数据共享的的问题。
  • C++类中数据成员类型时,定义为对象还是定义为指针? http://www.cppblog.com/aurain/archive/2012/11/18/195327.html C++,ClassTest objTest;就已经构造了对象,分配了空间;而C#,JavaClassTest...
  • 在C++,类的静态成员(static member)必须在类内声明,在类外初始化,像下面这样。class A { private: static int count ; // 类内声明 };int A::count = 0 ; // 类外初始化,不必再static关键字为什么?...
  • 所以不能在类声明初始化 const 数据成员,因为类的对象未被创建时,编译器不知道const 数据成员的值是什么。  const 数据成员的初始化只能在类的构造函数的初始化表进行。要想建立在整个类中都恒定的常量,应
  • 数据结构:八大数据结构分类

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

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

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

    千次阅读 2018-09-03 16:04:20
    一、声明静态成员 ...2、的静态成员存在于任何对象之外,对象不包含任何与静态数据成员有关的数据,静态数据成员被所有该类型的对象共享。 3、静态成员函数也不与任何对象绑定一起,它们不包...
  • 【C++】类中静态成员的声明、初始化类中静态成员的声明初始化静态数据成员值的改变完整例子 有参考大佬 零点零一 的文章:https://blog.csdn.net/thanklife/article/details/78476737 类中静态成员的声明 类中的静态...
  • C++-- 如何在类外访问一个类私有的成员变量?

    万次阅读 多人点赞 2018-08-24 11:07:14
    如何在类外访问一个类私有的成员变量? 我在网上搜答案的时候看到大部分回答都是在类内部创建一个接口,所以此方法我就不再多做赘述,今天我说的方法是利用指针的方法。 话不多说,上代码: class Test { ...
  • C++的静态变量成员与静态成员函数 ...静态成员变量必须在类外所定义,定义时不能添加static关键字 静态成员函数没有默认的this指针,因为它里面不能使用任何非静态成员 静态成员和普通的类成员...
  • 【C++深度剖析教程5】C++中类的静态成员函数

    万次阅读 多人点赞 2017-12-15 01:35:29
    先给大家推荐一个C++面试题集锦吧,保证能让你众多面试者脱颖而出,点击连接:C++面试题点播一在上一篇文章我们讲了C++中类的静态成员变量,用的静态成员变量实现了统计程序运行期间的某个类的对象的数目(不...
  • 静态数据成员: 就是说这个类中是固定的,只有一个。比如说中国人是一个,那么这个中国人的总人口数就是一个静态数据成员,这个静态数据成员不会跟随某个具体的人,而是正对于这个的。静态成员函数,一般这些...
  • 在类成员函数可以访问同类型实例的私有变量。 c. 拷贝构造函数里,可以直接访问另外一个同类对象(引用)的私有成员。 d. 类的成员函数可以直接访问作为其参数的同类型对象的私有成员。 举例描述上述知识...
  • C++:可变数据成员

    千次阅读 2016-04-05 16:38:37
    有时候(但不频繁)会发生这样一种情况:我们希望能修改某个数据成员,即使是一个const成员函数内,此时可以通过变量声明加入mutable关键字做到这一点。换句话说,如果某个数据成员被声明为 mutable,则从 ...
  •  new Book("数据结构与算法(c语言)",38),  new Book("Java程序设计 实例操作",59.8)};  System.out.println("图书总数为:"+ Book.HAOMA());  for(Book b:books){  System.out.println(b.toString());  }  ...
  • 的const成员变量2009/07/08 12:38 有时我们希望某些常量只在类中有效。由于#define定义的宏常量是全局的,不能...  不能在类声明初始化const数据成员。以下用法是错误的,因为类的对象未被创建时,
  • 类成员

    千次阅读 2012-02-17 15:54:07
    的所有成员都可以声明为public(此时可以在类的外部直接访问它们)或private(此时,它们只能由类的其他代码来访问)。C#protected(表示成员仅能由该成员所在的类及其派生类访问) 数据成员 数据成员包含了类的...
  • static数据成员与static成员函数

    千次阅读 2013-05-13 11:51:45
    静态数据成员的初始化必须在类以外进行定义性说明。 形式为:类型> 类名>::静态数据成员> =值 静态成员注意以下几点: 1、静态成员必须初始化,如果其是有公共访问属性的可以通过对象重新设置值,其最终值以...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 421,744
精华内容 168,697
关键字:

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