兜兜10

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 :: 管理 ::

一、结构体
          1、结构体定义
                              struct BOOK
                              {
                                  char Title[80];
                                  char Author[80];
                                  char Publisher[80];
                                  int Year;
                              };
          2、结构体变量声明
                             BOOK Novel;
          3、初始化结构体
                             BOOK Novel=
                             {
                                "Paneless Programming",
                                "I.C.Fingers",
                                "Gutter press",
                                1981
                             };                             这些初始化值位于大括号内,相互之间以逗号分开,这种方式与为数组成员定义初值的方式完全相同。
          4、访问机构成员
                              Novel.Year=1988;
                             
          5、使用指针处理结构
                              BOOk* pBook=NULL;
                              pBook=&Novel;
                             
                              RECT aRect={0,0,100,100};
                              RECT* pRect=&aRect;
                              (*pRect).Top+=10;
                             
                              pRect->Top+=10;
          6、包含自己指针的结构
                              struct ListElement
                              {
                                  BOOK aBook;
                                  ListElement* pNext;
                              };
             
二、类        
         1、类的定义
         class CBox
         {
            private:                                        类的私有成员。
                double m_Length;
                double m_Width;
                double m_height;
                char *pmessage;
                friend double BoxSurface(CBox aBox);        类的友元函数定义。
            public:                                                          类的公有成员。
               
                static int objectCount;                               类的静态数据成员。 所有的类的对象都共享一个此成员。
                                                                               int CBox::objectCount=0;  采用此方法初始化此成员。
                                                                               可以通过CBox::objectCount 或者 对象.objectCount 访问此变量。
                                                                               既是没有任何对象存储,类的static成员也可能存在。
                                                                               静态数据成员在程序启动时候自动创建,并被初始化为0. 如果我们希望
                                                                               静态数据成员最初是非零值时,才需要我们初始化它们。
                                                           
                static void Afunction(int n);                        静态成员函数的定义:既是本类的任何对象不存在,也可以调用静态成员函数。
                                                                              这种情况下,静态成员函数只能使用静态数据成员。 反之如果对象存在了。就可以访问
                                                                               对象的数据成员了。
                                                                              例如:aBox.Afunction(10);   或者 CBox::Afunction(10);
               
                double volume(void);
                double GetLength(void);
                double GetWidth(void) const;                    定义为const函数,其作用是使该函数中的this指针为const。
                                                                              我们不能在该函数的定义内赋值语句左边些上类的数据成员。
                                                                              const成员函数不能调用同类的非const成员函数。
                                                           
                CBox(){};                                               默认构造函数,如果不给类定义任何构造函数则编译器定义默认构造函数,反之
                                                                              如果给定义了构造函数,那么编译器不在给类定义默认构造函数。如果需要则需要人工定义。
                CBox(double lv,double bv,double hv);        构造函数的定义  
                CBox(double lv=1.0,double bv=1.0,double hv=1.0);        在类定义中指定默认的形参值。  如果有此函数 则需要去掉 默认构造函数。       
               
                CBox(const char* text="Default message");
                CBox(double lv=1.0,double bv=1.0,double hv=1.0):
                        m_Length(lv),m_Width(bv),m_Height(hv)              在构造函数中使用初始化列表。
                       
                CBox(const CBox& initB);                          复制构造函数的定义。 复制构造函数是通过用同类的现有对象进行初始化,
                                                                         从而创建新对象的构造函数,因此需要接受同类的对象作为实参。
                                                           
                ~CBox();                                                 析构函数用于销毁不再需要或者不再有效的对象.
                void ShowIt() const;
                bool operator>(const CBox& aBox) const;           重载>运算符
         };
        
         double CBox::Volume()
         {
            return m_length*m_Width*m_Height;
         }
         inline double CBox::GetLength()                    内联函数,相当于把函数体复制到调用的地方。访问类的私有成员。
         {
            return m_Length;
         }
         CBox::CBox(double lv,double bv,double hv)          构造函数的实现
         {
           m_Length=lv;
           m_Width=bv;
           m_Height=hv;
         }
         CBox(double lv=1.0,double bv=1.0,double hv=1.0)  默认形参值的函数实现部分。
         {
           m_Length=lv;
           m_Width=bv;
           m_Height=hv;
         }
         double BoxSurface(CBox aBox)                                此函数虽然不是类成员的函数,但是确能访问类的所有成员。
         {                                                                           可以在类定义中包括友元函数的原型,可以可以包括真个函数定义。
             return 2.0*(aBox.m_Length*aBox.m_Width+        在类定义内定义的类的友元函数默认也是内联函数。
                         aBox.m_length*aBox.m_Height+              友元函数不是类的成员。因此访问特性不适用它们。这些函数只是拥有
                         aBox.m_Height*aBox.m_Width);              特殊权限的普通全局函数。
         }
         double CBox::GetWidth(void) const                          const成员函数的实现。
         {
            return this->m_Width;
         }
         CBox::CBox(const CBox& initB)                                 复制构造函数的实现。
         {
             m_Length=initB.m_Length;
             m_Width=initB.m_Width;
             m_Height=initB.m_Height;
            
             pmessage= new char[strlen(initB.pmessage)+1];   因为的对象的成员pmessage是new动态分配的,在复制构造中,复制只能复制到对象的地址,
             strcpy(pmessage,initB.pmessage);                       如果一个对象释放,那么另外一个对象的成员也被释放,为了避免这个问题,需要手动复制
                                                                                     成员对象内存的实际数据.
         }
         CBox::~CBox()                                                     一般我们不需要显式调用析构函数,当某个对象无效时,编译
         {                                                                          器将自动安排调用给类的析构函数.
            cout<<"Destructor called."<<endl;                       系统函数,释放构造函数分配的内存.
            delete[] pmessage;
         }
         CBox::CBox(const char* text="Default message")      构造函数
         {
            pmessage= new char(strlen(text)+1);
            strcpy(pmessage,text);
         }
         void CBox::ShowIt() const
         {
            cout<<endl<<pmessage;
         }
         void DisplayMessage(CBox,localBox)                                 这样致命的错误是,形参是按值传递,localBox是调用了复制构造函数形成的
         {                                                                                   原本对象的副本.如果这个函数调用完,localBox释放,那么就随即释放了实参的成员.
            cout<<endl<<"The message is:"<<localMsg.ShowIt();     如果在调用实参的,成员变量内容,则是一个随即的数据,如果以后在把此对象作为其他
            return;                                                                        函数的实参,那么这个对象成员变量所指的对象都是一个随即的数据.
         }
         bool CBox::operator>(const CBox& aBox) const                >运算符重载的实现
         {
            return this->Volume()>aBox.Volume();
         }
         2、类对象使用
                             CBox boxes[5];                                        声明对象数组,将调用CBox的默认构造函数。
                             CBox MyBox;                                           定义CBox变量,将调用CBox的默认构造函数。
                             CBox MyBox1(2,3,4);                               定义CBox变量,将调用CBox的自定义构造函数。
                            
                             MyBox.Volume();                                     对象访问成员函数。
                            
                             BoxSurface(MyBox1);                               访问友元函数,跟普通的函数调用是一样的。
                             MyBox.GetWidth();                                  访问对象的const成员函数。
                            
                             CBox Box=MyBox1;                                 用对象MyBox1初始化Box,调用的是对象的复制构造函数。
        
         3、类对象的指针很引用
                             CBox* pBox=0;                                      声明对象指针。
                             pBox=&cigar;                                          给对象指针赋值。
                             count<<pBox->Volume();                        通过指针访问对象的成员函数。
                            
                            
                             CBox& rcigar=cigar;                                 类引用的定义。
                             cout<<rcigar.Volume();                            通过引用访问对象成员函数。
                            
                             CBox* pbox= new CBox("A cat can look at a queen.");    有指针动态初始化对象,
                             pbox->ShowIt();                                                          指针调用对象的方法.
                             delete pbox;                                                                删除对象指针,只有这个对象指针是new分配的时候,才需要.

三、联合
          1、联合的定义
                              union shareLD                  dval和lavl公有一块内存,如果dval给赋值,那么就覆盖了lval。
                              {
                                 double dval;
                                 long lval;
                              };
          2、联合变量的声明
                              shareLD myUnion;    或者
                              union shareLD
                              {
                                 double dval;
                                 long lval;
                              }myUnion;
          3、联合变量使用
                              myUnion.lval=100;   
          4、联合的初始化                                   联合占用的内存大小取决于最大的成员。
                              union shareDLF                |---------------8个字节--------------|
                              {                                    |___|___|___|___|___|___|___|___|
                                  double dval;                 |----avl4个字节----|
                                  long lval;                      |                         |
                                  float fval;                     |----favl4个字节---|
                               }uinst={1.5};                 |                         |
                                                                    |--------------dval8个字节-----------|   
                                                           当声明实例时,我们只能初始化联合的第一个成员。
          5、匿名联合
                              union
                              {
                                 char* pval;
                                 double dval;
                                 long lval;
                              }      

四、重载运算符
          运算符重载功能不允许我们使用新的运算符,也不允许我们改变运算符的优先级。
          不能重载的运算符:  ?:,  .,  sizeof, .*,::  
         
          class Length
          {
              private:
                   double len;
                
               public:
                   Length& operator++();                    前加运算符
                   const length operator++(int);           后加运算符
                  
                   Length& operator--();                      前减运算符
                   const Length operator--(int);           后减运算符
           }                                  
          
           Length& Length::operator++()                  前加运算符的实现
           {
               ++(this->len);
               return *this;
           }
          
           const Length& Length::operator++(int)          后加运算符的实现,返回const,以防止类似data++这样的表达式被编译。
           {
              Length length=*this;
              ++*this;
              return length;
            }
五、类模板    
          1、定义类模板
                    template<class T>                       任何用来根据模板实例化某个类的类类型,都必须已经定义过模板的成员函数
                    class CSamples                           处理本类对象时要用到的所有运算符。
                    {
                        public:
                            CSamples(const T values[],int count);   构造函数在外部实现
                            CSamples(const T& value)
                            {
                                m_Values[0]=value;
                                m_Free=1;
                            }
                            CSamples(){m_Free=0}
                            bool Add(const T& value)
                            {
                               bool OK=m_Free<100;
                               if(OK)
                                  m_Values[m_Free++]=value;
                               return OK:
                            }
                            T Max() const;                         在模板类外实现的函数

                       private:
                            T m_Values[100];
                            int m_Free;
                     };
                     template<class T>                               作用域解析运算符之前只能使用附带形参名称T的模板名。这是必须的。
                     T CSamples<T>::Max() const               形参识别出根据该模板生成的函数属于那个类非常重要。
                      {                                                       类模板的类型是CSamples<T>,其中T是我们创建类模板实例时指定的类型。
                          T theMax=m_Free?m_values[0]:0;    CSamples<T>::前面的T是Max函数的返回值。
                          for(int i=1;i<m_Free;i++)
                             if(m_Values[i]>theMax)
                                theMax=m_Values[i];
                          return theMax;
                      }
                      template<class T> 
                      CSamples<T>::CSamples(const T values[],int count)  在外部实现的构造函数。注意没有返回值
                      {
                        m_Free=count<100?count:100;
                        for(int i=0;i<m_Free;i++)
                           m_Values[i]=values[i];
                      }  
          2、根据类模板创建对象
                      CSamples<double> myData(10.00);                 为了声明一个CSamples<>对象来处理double类型的样本。

posted on 2010-12-09 14:25  兜兜10  阅读(133)  评论(0)    收藏  举报