现在的位置: 首页 > 综合 > 正文

C++ How To Program整理(6)

2013年11月11日 ⁄ 综合 ⁄ 共 4675字 ⁄ 字号 评论关闭

这部分依旧是类的解析。
@const对象的定义:const Time time;对于const对象,除非成员函数本身也声明为const,不然不允许进行成员函数的调用,也就是说const对象只能调用声明为const类型的成员函数。
@声明const函数的方法,既要在声明中指定(原型中),又要在定义中指定,方法是在函数形参列表后和函数体开始前加入关键字const。
@定义为const的成员函数如果又调用同一类中同一实例的非const函数将会出错。
@既然有重载,可以对const成员函数进行非const 的重载,就可以解决这个问题了。

    class Time
    {
      public:
            Time(int =0, int =0 ,int =0)
           
            void setTime(int ,int ,int);
            void setHour(int);
            void setMinute(int);
            void setSecond(int);
           
            int getHour() const;
            int getMinute() const;
            int getSecond() const;
   
    }
    #endif
       
    #include<iostream>
    #include"Time.h"
    #include<iomanip> 
    using namespace std;
   
   .......忽略部分代码
 
  
   void Time::printUniversal()
   {
      cout<<setfill('0')<<setw(2)<<hour<<":"<<setw(2)<<minute<<":"<<setw(2)<<second;
   }
  
   void Time::printStandard()
   {
  
      cout<<((hour==0||hour==12)?12:hour%12)<<":"<<setfill('0')<<setw(2)<<minute<<":"<<setw(2)<<second<<(hour<12?"am":"pm");
   }
         
        int Time::getHour() const
        {
          return hour;   
        }
       
@构造函数必须是非const函数,但是它不受以上条款限制,可以用来初始化const对象,并且在构造函数中可以调用非const函数来初始化const对象。
@我们从上条可以知道,const常量的性质是从构造函数执行完之后,到析构函数调用结束。
@所有的数据成员都可以使用成员初始化器进行初始化,最重要的是const数据成员和引用数据成员必须使用成员初始化器进行初始化,成员对象也必须使用这一种方法初始化。
@成员初始化器出现在构造函数参数列表的构造函数体的左括号之间,以“:”开始,成员之间用“,”分开。
比如 Time::Time(int m ,int n):a(m),b(n)
     {
 
    }
    其中a和b是定义的int型的const 变量,const对象不能通过赋值修改,所以必须被初始化,当某个数据成员声明为const时,就必须使用相应的成员初始化器。

下面的代码说民构造函数如何通过成员初始化器来完成将参数传递给成员对象构造函数的。

Data 类

#ifndef DATE_D
#define DATE_D

class Date
{
   public:
          static const int monthsPerYear=12;
          Date(int =1,int =2,int =1900);
          ~Date();
   private:
          int month;
          int day;
          int year;
       
      int checkDay(int) const;
  };
 
#endif

#include<iostream>
#include"Date.h"

using namespace std;

......省略

下面定义Employee类,包含Date对象

#ifndef  EMPLOYEE_H
#define EMPLOYEE_H

 #include<iostream>
 #include "Date.h"
 using namespace std;
 
 class Employee
 {
     public:
           Employee(const string &,const string &,const Date&, const Date&);
           void print() const;
           ~Employee();
    private:
           string firstName;
           string lastName;
           const Date birthDay;
           const Date hireDay;                
 };
 
 Employee类的实现
 只看构造函数初始化部分
 Employee::Employee(const string &first ,const string &last,const Date& dateOfBirth, const Date&dateOfHire)
                  :firstName(first),lastName(last),birthDay(dateOfBirth),hireDay(dateOfHire)
       {
       }
      
      
  测试用例客户代码:
       Date birth(7,24,1949);
       Date hire (3,12,1988);
      
       Employee manager(“bob”,“blue”,birth,hire );    
      
@类的friend函数在类的作用域之外定义,却具有访问类的非public函数的能力,单独的函数或者整个类都可以被声明为另一个类的友元。
@在类定义中函数原型前面加上friend,就将该函数声明为该类的友元,要将class two的所有成员函数声明为class one的友元,应在class one定义中加入如下声明:
   friend classTwo;
@即使friend函数的原型在类定义中出现,友元仍不是成员函数。
@private public和protected成员访问符与友元的声明无关,因此友元定义可以放在类定义的任何地方。
@一个良好的编程习惯是将友元声明放在类定义中的最前面并且不加访问符。
@友元关系是授予的,而不是获取的,意味着要想B成为A的友元,必须要在A中显示的声明类B是它的友元。
@友元关系既不对称又不可传递,意味着如果A是B的友元,B是C的友元,那么A并不是C的友元。
#include<iostream>
using namespace std;

class Count
{
    friend void setX(Count &, int);
  public:
       Count():x(0
       {}
      
       void print()
       {
        cout<<x<<endl;      
       }
  private:
    int x;
 };
     void setX(Count &c, int val)
     {
       c.x=val;
     }     
    
     int main()
     {
       Count counter;
      
       cout<<"count.x after call to setX friend function:"<endl;
       counter.print();
       setX(counter,8);
       cout<<"count.x after call to setX friend function:"<endl;
       counter.print();
     }

由此看来,在引用和友元问题上,安全性确实是个问题。
@this指针作为一个隐式的参数,由编译器传递给对象的每个非static成员函数,this指针不是对象的一部分,所以其大小不会反应在对象上。
@this指针的类型取决于对象类型以及使用this的成员函数是否为const,例如在A类的非const函数,this指针的类型是A ×const,在A的const函数上是const A *const.
 两种简单的方式介绍this
 (1):隐式或显示使用this指针来访问对象的数据成员。
 
  #include<iostream>
 
  using namespace std;
 
  class Test
  {
    public:
         Test(int =0);
         void print() const;
    private:
        int x=0;
  };
 
  Test::Test(int value):x(value)
  {
  }          
   void Test::print() const
   {
    cout<<"  x="<<x<<endl;
   
    cout<<"  this->x="<<this->x<<endl;
    cout<<"  (*this).x"<<(*this).x<<endl;
     
   }     
 
  int main()
  {
    Test testObject(12);
    testObject.print();
  }
 
 (2)使用this指针可以使多个函数在同一个语句中被调用(函数串联调用)
  原型声明:
  Time &setTime(int, int ,int);
  Time &setHour(int);
  Time &setMinute(int);
 定义:
 Time &setTime(int, int ,int)
 {
   return *this;
 }
  Time &setHour(int, int ,int)
 {
   return *this;
 }
    Time &setMinute(int, int ,int)
 {
   return *this;
 }
 
 使用:
 Time t;
    t.setTime(1,2,3).setHour(2).setMinute(3);
    圆点运算符的运算时从右向左的,所以以上你就懂了
   
 @正常情况下每个对象都有数据成员的一份副本,但是static成员只有一份副本,供所有对象公用,static数据成员只在类的作用域起作用,跟全局变量没毛关系。
 @默认情况基本类型的static数据成员被初始化为0。
 @static数据成员仅能初始化一次。
 @在没有类的对象存在时,想访问类的public static成员只需要在数据成员前面加上类名和“::”
 @static函数不具有this指针,因为static数据成员或函数独立于任何类的对象,而this指针必须指向类的具体对象。
 @const限定符指示函数不修改它操作的对象的内容,但是static成员函数独立于对象,所以static函数不能声明为const。
 
   
  
  
 
       

抱歉!评论已关闭.