#include <iostream.h>
class POINT
{
public:
int x;
int y;
POINT()//構造函數
{
x=0;
y=0;
}
void output()
{
cout<<x<<endl<<y<<endl;
}
};
void main()
{
POINT pt;//在定義類的變量時自動調用構造函數
pt.output();
}
1.類裏面默認的成員爲私有,結構體裏面的成員變量爲公有
2.構造函數,在main函數定義類變量時,自動調用構造函數
3.析構函數,不允許帶參數,並且一個類中只能存在一個析構函數
4.函數的重載,我們希望在構造pt這個對象的同時,傳遞x座標和y座標的值.可以再定義一個構造函數.兩個構造函數
#include <iostream.h>
class POINT
{
public:
int x;
int y;
POINT()//構造函數
{
x=0;
y=0;
}
POINT(int a,int b)
{
x=a;
y=b;
}
void output()
{
cout<<x<<endl<<y<<endl;
}
};
void main()
{
POINT pt(5,5);//在定義類的變量時自動調用構造函數
pt.output();
}
C++編譯器將根據參數的類型和參數的個數來確定執行哪一個構造函數,如上執行POINT(int a,int b)
重載的條件:函數的參數類型,參數個數不同,才能構成重載 只有返回類型不同是不能構成重載的
this 指針 它是一個隱含的指針,在調用對象時,成員函數除了接受2個實參外,還接受了pt對象的指針
#include <iostream.h>
class POINT
{
public:
int x;
int y;
POINT()//構造函數
{
x=0;
y=0;
}
POINT(int a,int b)
{
x=a;
y=b;
}
void output()
{
cout<<x<<endl<<y<<endl;
}
void input(int x,int y)
{
this->x=x;
this->y=y;
}
};
void main()
{
POINT pt(5,5);//在定義類的變量時自動調用構造函數
pt.input(10,10);
pt.output();
}
類的繼承
#include <iostream.h>
class animal
{
public:
void eat()
{
cout<<"animal eat"<<endl;
}
void sleep()
{
cout<<"animal sleep"<<endl;
}
void breath()
{
cout<<"animal breath"<<endl;
}
};
class fish:public animal
{
};
void main()
{
animal an;
fish fh;
an.eat();
fh.eat();
}
在c++中提供了一種重要的機制,就是繼承。我們可以基於animal這個類來創建fish類,animal稱爲基類.fish稱爲派生類.
class fish:public animal//fish繼承animal
{
};
爲基類和派生類加入構造函數和析構函數
#include <iostream.h>
class animal
{
public:
animal()
{
cout<<"animal construct"<<endl;
}
~animal()
{
cout<<"animal destruct"<<endl;
}
void eat()
{
cout<<"animal eat"<<endl;
}
void sleep()
{
cout<<"animal sleep"<<endl;
}
void breath()
{
cout<<"animal breath"<<endl;
}
};
class fish:public animal
{
public:
fish()
{
cout<<"fish construct"<<endl;
}
~fish()
{
cout<<"fish destruct"<<endl;
}
};
void main()
{
fish fh;
}
當構造fish類的對象fh時,animal類的構造函數也要被調用,而且在fish類的構造函數調用之前被調用.當然,這也很好理解,沒有父親就沒有孩子,在析構時,先析構派生類再析構基類.
#include <iostream.h>
class animal
{
public:
animal(int height,int weight)//基類構造函數帶參數
{
cout<<"animal construct"<<endl;
}
~animal()//析構函數都不帶參數
{
cout<<"animal destruct"<<endl;
}
void eat()
{
cout<<"animal eat"<<endl;
}
void sleep()
{
cout<<"animal sleep"<<endl;
}
void breath()
{
cout<<"animal breath"<<endl;
}
};
class fish:public animal
{
public:
fish():animal(400,300)
{
cout<<"fish construct"<<endl;
}
~fish()
{
cout<<"fish destruct"<<endl;
}
};
void main()
{
fish fh;
}
public定義的成員可以在任何地方被訪問
protected定義的成員只能在該類及其子類中訪問
private定義的成員只能在該類自身中訪問
對於繼承,也可以有以上三種訪問權限去繼承基類中的成員
注意:基類中的private成員不能被派生類訪問,因此,private成員不能被派生類所繼承.
多重繼承:一個類可以從多個基類中派生。在派生類由多個基類派生的多重繼承模式中。多重繼承的語法與單一繼承很類似,只需要在聲明繼承的多個類之間加入逗號來分割。
虛函數與多態性,純虛函數:
#include <iostream.h>
class animal
{
public:
void eat()
{
cout<<"animal eat"<<endl;
}
void sleep()
{
cout<<"animal sleep"<<endl;
}
void breath()
{
cout<<"animal breath"<<endl;
}
};
class fish:public animal
{
public:
void breath()//在fish類中重新定義了breath()方法,吐泡泡
{
cout<<"fish bubble"<<endl;
}
};
void fn(animal *pAn)//全局函數fn()
{
pAn->breath();
}
void main()
{
animal *pAn;
fish fh;//定義了一個fish類的對象
pAn=&fh;//將它的地址傳給animal類的指針變量
fn(pAn);//調用fn()
}
main函數中,定義了一個全局函數fn(),指向animal類的指針作爲fn()函數的參數。
我們將fish類的對象fh的地址直接賦值給了animal類的指針變量
這是因爲fish對象也是一個animal對象,將fish類型轉換爲animal類型不用強制類型轉換。
virtual void breath()
{
cout<<"animal breath"<<endl;
}
用virtual關鍵字申明的函數叫做虛函數。C++會採用遲綁定計數。也就是編譯時並不確定具體調用的函數,而是在運行時,依據對象的類型來確定調用的是哪一個函數,這種能力就叫做c++的多態性
即:在基類的函數前面加上virtual關鍵字,在派生類中重寫該函數,運行時將會根據對象的實際類型來調用相應的函數。如果對象類型是派生類,就調用派生類的函數;如果對象類型是基類,就調用基類的函數。
純虛函數:
純虛函數可以讓類先具有一個操作名稱,而沒有具體的操作內容,讓派生類再繼承時在去具體的給出定義。凡是含有純虛函數的類叫做抽象類,這種類不能聲明對象,只是作爲基類爲派生類服務。在派生類中必須完全實現基類的純虛函數,否則,派生類也變成了抽象類,不能實例化對象。
函數的覆蓋:
*基類函數必須是虛函數。
*發生覆蓋的兩個函數分別位於派生類和基類中。
*函數名稱與參數列表必須完全相同。
函數的隱藏:
所謂隱藏,是指派生類中具有與基類同名的函數,從而在派生類中隱藏了基類的同名函數。
區分覆蓋和隱藏:
函數的覆蓋是發生在派生類與基類之間,兩個函數必須完全相同,並且都是虛函數。那麼不屬於這種情況的,就是隱藏了.
C++類的設計習慣及頭文件重複包含問題的解決
在設計一個類的時候,通常將類的定義及類成員函數的聲明放到頭文件(即.h文件)中,將類中成員函數的實現放到源文件中
(.cpp)中
對於animal類需要把animal.h和animal.cpp兩個文件,其餘類相同
對於main()函數,我們把它單獨放到EX10.cpp文件中.