1. 程式人生 > >虛擬函式,純虛擬函式,抽象類,點H與點CPP檔案的結合

虛擬函式,純虛擬函式,抽象類,點H與點CPP檔案的結合

我居然可以將if…else if和if…if一視同仁,這是變瞎的前兆嗎?

題目:列印當月每個週日的日期和週日總的次數

#include<stdio.h>
int main()
{
    int i = 1,j = 1;
    for(i = 1;i <= 31;i++)
    {
        if(i ==3)
            printf("第%d個週日是:%d號",j,i);
        if((i - 3)%7 == 0)
        {
            j++;
            printf("第%d個週日是:%d號",j,i);
        }
    }
    printf
("七月總共有%d個週日",j); getchar(); return; }

然後我就發現週五的總數比正確答案多了一個,因為兩個if在判斷時出現重複,那就是i==3的情況,用if…else if…就對了。

回顧一下,很多的地方很模糊,甚至是不理解從近往遠說:
1,不同情況下建構函式的呼叫順序。
2,共用體的在記憶體裡面的儲值方式和規則。(週末時遇到的問題:關於double型成員最先賦值和最後賦值時遠行出兩種不同的結果我我還是無法理解)
3,我對列舉體這個東西存在的意義很疑惑,通俗點,現階段看來,我覺得它沒有什麼卵用。
4,結構體成員裡面包含有陣列的問題。
5,函式的遞迴我從來不敢掉以輕心。
6,各種資料型別的轉換問題,精度缺失問題的內部成因不是特別清晰。

- - - - - - - - - - - - - - - - - - 今日內容- - - - - - - - - - - - - - - - - -

- - - - - - - - - - - - - - - - - - - 多型- - - - - - - - - - - - - - - - - - - -

多型的第一個方式

1.建立類,並且定義虛擬函式
2.虛擬函式作用,讓每個類都可以覆蓋這個方法的內容
3.如果我的類中有純虛擬函式就預設為抽象類
4.抽象類是不允許建立物件的

虛擬函式區別與普通函式的一個標誌:virtual
純虛擬函式的定義方式:virtual void callme() = 0;

虛擬函式跟過載函式是兩個概念,在基類定義了虛擬函式以後,在繼承類裡面可以改方法體,實現不同功能,這是一種覆蓋。

重點:點H檔案與CPP檔案的繫結:
1,點H檔案的名稱與該檔案下的類名一致
2,點H檔案下的類內部值負責成員函式的宣告,具體的功能實現在CPP檔案裡完成。

應用點H檔案的方式:

#include”Base.h” //表示應用了名為Base的標頭檔案
#ifndef BASE_H //必須有(雖然我不明白原理)
#define BASE_H
#endif //與ifndef同在,必須有(雖然我不明白原理)

什麼是宣告,什麼是定義

1,宣告是不分配記憶體的,定義才會分配記憶體。
2,基本資料型別(int,char,float,double)宣告就是定義,比如int i;它既是宣告也是定義。
3,僅代表對基本資料型別專門宣告的情況只有一種:extern int i,代表i這個變數是在別的地方定義了(如果你發現在接下來的程式碼中i是有一個固定值的,請不要大驚小怪)
4,函式,結構體,公用體,類的宣告與定義的區別就很明顯,不做贅述。

代表性的題目:

寫一個程式,定義一個帶有純虛擬函式的基類Shape,由它派生出5個派生類:圓形(Circle)、矩形(Rectangle)、正方形(Square)、三角形(Triangle)、梯形(Trapezoid)。實現基類中的虛擬函式,分別計算幾種圖形的面積。要求:使用基型別的指標陣列,使陣列的每個元素分別指向一個派生類的物件。使用多型的概念實現對於求面積方法的呼叫。並給出適當的輸入輸出提示。

#include<iostream>
#include<string>
using namespace std;
#define PI 3.14

/*基類-形狀*/
class Shape
{
public :
    virtual void area() = 0;   //純虛擬函式   
};


/*圓形*/
class Circle: public Shape
{
public :
    void area()
    {
        cout<<"\n"<<"輸入圓的半徑:"<<endl;
        cin>>r;
        getchar();
        cout<<"面積: "<<PI*r*r<<endl;
    }
private:
    double r;   
};

/*矩形*/
class Rectangle: public Shape
{
public :
    void area()
    {
        cout<<"\n"<<"輸入矩形的長,寬: "<<endl;
        cin>>len;
        getchar();
        cin>>wigth;
        getchar();
        cout<<"面積: "<<len*wigth<<endl;
    }
private:
    double len,wigth;
};

/*正方形*/
class Square : public Shape
{
public :
    void area()
    {
        cout<<"\n"<<"輸入正方形的邊長"<<endl;
        cin>>L;
        getchar();
        cout<<"面積: "<<L*L<<endl;
    }
private:
    double L;
};

/*三角形*/
class Triangle: public Shape
{
public :
    void area()
    {
        cout<<"\n"<<"輸入三角形的底邊長,高"<<endl;
        cin>>L1;
        getchar();
        cin>>higth1;
        getchar();
        cout<<"面積: "<<L1*higth1<<endl;
    }
private:
    double L1,higth1;

};

/*梯形*/
class Trapezoid: public Shape
{
public :
    void area()
    {
        cout<<"\n"<<"輸入梯形的底邊長,高"<<endl;
        cin>>L2;
        getchar();
        cin>>higth2;
        getchar();
        cout<<"面積: "<<L2*higth2<<endl;
    }
private:
    double L2,higth2;

};

int main()
{   
    Shape*a[5];
    a[0] = new Circle;
    a[0]->area();
    a[1] = new Rectangle;
    a[1]->area();
    a[2] = new Square;
    a[2]->area();
    a[3] = new Triangle;
    a[3]->area();
    a[4] = new Trapezoid;
    a[4]->area();
    getchar();
    return 0;
}