天天看點

C++學習筆記第三天:類、虛函數、雙冒号

class Box
{
   public:
      double length;   // 盒子的長度
      double breadth;  // 盒子的寬度
      double height;   // 盒子的高度
};      

類成員的作用域:

public:公共成員。通路權限:外部、子類、本身

protected:受保護成員。通路權限:子類、本身

private:私有成員。通路權限:本身

構造函數

跟其他語言一樣,使用類名作為函數名,無傳回值,可以有參數。

#include <iostream>
 
using namespace std;
 
class Line
{
   public:
      void setLength( double len );
      double getLength( void );
      Line();  // 這是構造函數
 
   private:
      double length;
};
 
// 成員函數定義,包括構造函數
Line::Line(void)
{
    cout << "Object is being created" << endl;
}
 
void Line::setLength( double len )
{
    length = len;
}
 
double Line::getLength( void )
{
    return length;
}
// 程式的主函數
int main( )
{
   Line line;
 
   // 設定長度
   line.setLength(6.0); 
   cout << "Length of line : " << line.getLength() <<endl;
 
   return 0;
}      

如果是帶參數的構造函數,可以使用初始化清單:

Line::Line( double len): length(len)
{
    cout << "Object is being created, length = " << len << endl;
}      

上面的文法等同于如下文法:

Line::Line( double len)
{
    cout << "Object is being created, length = " << len << endl;
    length = len;
}      

如果有多個參數,中間用逗号隔開:

Line::Line( double len): length(len), para02(var02)
{
    cout << "Object is being created, length = " << len << endl;
}      

另外,初始化清單并不是構造函數專用的,類的普通成員函數也可以使用。

析構函數

這個挺新鮮的,作用跟構造函數正好相反,在對象被銷毀的時候執行。

無傳回值,無參數,是以無法重載,一個類隻能有一個析構函數

函數名也是與類同名,隻需要在前面加一個波浪線前桌:~

在析構函數中,主要用來銷毀在構造函數或成員方法裡 new 出來的對象或指針,最常用的就是:delete obj

#include <stdio.h>  
#include <iostream>  
#include <vector>  
using namespace std;  

struct CP  
{  
    int a;  
    int b;  
};  

class TEST  
{  
    public:  
        CP* compound;  
        int num;  
    TEST(){  
        compound = new CP();  
        cout << "create a new TEST obj" << endl;  
    };  
    ~TEST(){  
        cout << "delete TEST obj" << endl;  
        delete compound;  
    };  
};        

類的繼承

跟JAVA不同,C++中允許一個類繼承多個父類:

#include <iostream>
 
using namespace std;
 
// 基類 Shape
class Shape 
{
   public:
      void setWidth(int w)
      {
         width = w;
      }
      void setHeight(int h)
      {
         height = h;
      }
   protected:
      int width;
      int height;
};
 
// 基類 PaintCost
class PaintCost 
{
   public:
      int getCost(int area)
      {
         return area * 70;
      }
};
 
// 派生類
class Rectangle: public Shape, public PaintCost
{
   public:
      int getArea()
      { 
         return (width * height); 
      }
};
 
int main(void)
{
   Rectangle Rect;
   int area;
 
   Rect.setWidth(5);
   Rect.setHeight(7);
 
   area = Rect.getArea();
   
   // 輸出對象的面積
   cout << "Total area: " << Rect.getArea() << endl;
 
   // 輸出總花費
   cout << "Total paint cost: $" << Rect.getCost(area) << endl;
 
   return 0;
}      

輸出:

Total area: 35

Total paint cost: $2450

虛函數

這個不太好了解,隻能按照别人的描述硬性記憶:在類的成員函數前面加 virtual 表示該成員函數為虛函數。

虛函數在C++中的作用不低,很多官方的源碼中都存在大量的虛函數

目前位置能了解的作用包括:

1、允許用基類的指針來調用子類的這個函數:

class A  
{  
    public:  
        virtual void foo()  
        {  
            cout<<"A::foo() is called"<<endl;  
        }  
};  
class B : public A  
{  
    public:  
        void foo()  
        {  
            cout<<"B::foo() is called"<<endl;  
        }  
};  
int main(void)  
{  
    A *a = new B();  
    a->foo();   // 在這裡,a雖然是指向A的指針,但是被調用的函數(foo)卻是B的!  
    return 0;  
}      

2、通過“純虛函數”實作抽象類

虛函數:

virtual ReturnType funtion1(params...);      

虛函數在基類中可以有預設實作,派生類也可以覆寫;

但如果在基類中沒有預設實作,那麼派生類必須具體實作。

純虛函數:

virtual ReturnType funtion1(params...)=0;       

在虛函數聲明的後面加“=0”就表示這是一個純虛函數,含有純虛函數的類成為抽象類。

純虛函數用來規範派生類的行為,即接口。派生類中必須對這個純虛函數進行具體實作。

抽象類不能定義執行個體,但可以聲明指向實作該抽象類的具體類的指針或引用。

對虛函數的了解,有一個很好的比方:

比如你有個遊戲,裡面有個含有純虛函數 [攻擊] 的抽象類 [怪物],然後有三個派生子類 [狼]、[蜘蛛]、[蛇] 都繼承了 [怪物],并且都各自實作了自己獨特的 [攻擊] 函數。

那在出現怪物的時候就可以定義一個 虛基類指針數組,把各種怪物的指針給它,然後疊代循環的時候直接:怪物[i]->攻擊() 攻擊玩家就行了

Monster *pMonster[3];
pMonster[0] = new Wolf(); //初始化一匹狼
pMonster[1] = new Spider(); //初始化一隻蜘蛛
pMonster[2] = new Snake(); //初始化一條蛇

for(int i=0; i<3; i++){
    pMonster[i] -> attack(); //攻擊
}      

雙冒号(::)

1、調用 namespace 中的成員時,需要用 ::

2、在類的外部定義成員函數時,需要用::

3、差別兩個類中同名的成員變量或者函數時,需要用::

4、在成員函數内部調用同名的全局變量時,需要用::

5、調用類的靜态成員函數時,可以用::

寵辱不驚,看庭前花開花落;去留無意,望天上雲卷雲舒