1. 類和對象
class Box
{
public://private 或 protected
double length; // 盒子的長度
double breadth; // 盒子的寬度
double height; // 盒子的高度
double getVolume(void) //類的成員函數(shù)
{
return length * breadth * height;
}
Box();//構造函數(shù)
Box(double length);//帶參數(shù)的構造函數(shù)
~Box();//析構函數(shù)
Box(const Box &obj);// 拷貝構造函數(shù)
friend void printWidth( Box box ); //友元函數(shù)
private:
double *ptr;
};
Box::~Box(void)
{
cout << "Object is being deleted" << endl;
}
Box::Box(const Box &obj)
{
cout << "調用拷貝構造函數(shù)并為指針 ptr 分配內存" << endl;
ptr = new double;
*ptr = *obj.ptr; // 拷貝值
}
Box Box1;// 聲明 Box1,類型為 Box
Box Box2;// 聲明 Box2递宅,類型為 Box
// box 1 詳述
Box1.height = 5.0;
Box1.length = 6.0;
Box1.breadth = 7.0;
成員函數(shù)
除了可以在 class 內部定義成員函數(shù)娘香,也可以在類的外部使用范圍解析運算符 :: 定義該函數(shù),如下:
double Box::getVolume(void)
{
return length * breadth * height;
}
:: 叫作用域區(qū)分符办龄,指明一個函數(shù)屬于哪個類或一個數(shù)據(jù)屬于哪個類烘绽。
:: 可以不跟類名,表示全局數(shù)據(jù)或全局函數(shù)(即非成員函數(shù))俐填。
C++ 類訪問修飾符
public安接、private、protected英融,成員和類的默認訪問修飾符是 private盏檐。保護(protected)成員變量或函數(shù)與私有成員十分相似,但有一點不同驶悟,保護成員在派生類(即子類)中是可訪問的胡野,而 priavte 是不可以的。
類繼承時使用修飾符
有public, protected, private三種繼承方式痕鳍,它們相應地改變了基類成員的訪問屬性硫豆。
- 1.public 繼承:基類 public 成員,protected 成員笼呆,private 成員的訪問屬性在派生類中分別變成:public, protected
- 2.protected 繼承:基類 public 成員熊响,protected 成員,private 成員的訪問屬性在派生類中分別變成:protected, protected诗赌,有繼承下來但說父類的成員不能被子類對象調用了
- 3.private 繼承:基類 public 成員汗茄,protected 成員,private 成員的訪問屬性在派生類中分別變成:private, private境肾,有繼承下來但父類的成員不能被子類對象調用了
但無論哪種繼承方式剔难,上面兩點都沒有改變:
- 1.private 成員只能被本類成員(類內)和友元訪問胆屿,不能被派生類訪問;
- 2.protected 成員可以被派生類訪問偶宫。
class B : public A{
}
類的構造函數(shù)
會在每次創(chuàng)建類的新對象時執(zhí)行
注意一種帶初始化列表的構造函數(shù)
C::C( double a, double b, double c): X(a), Y(b), Z(c)
{
....
}
//eg:
Box::Box( double len): length(len)
{
cout << "Object is being created, length = " << len << endl;
}
//相當于
Box::Box( double len)
{
cout << "Object is being created, length = " << len << endl;
length = len;
}
類的析構函數(shù)
在每次刪除所創(chuàng)建的對象時執(zhí)行
析構函數(shù)的名稱與類的名稱是完全相同的非迹,只是在前面加了個波浪號(~)作為前綴,它不會返回任何值纯趋,也不能帶有任何參數(shù)憎兽。析構函數(shù)有助于在跳出程序(比如關閉文件、釋放內存等)前釋放資源吵冒。
C++ 拷貝構造函數(shù)
拷貝構造函數(shù)是一種特殊的構造函數(shù)纯命,它在創(chuàng)建對象時,是使用同一類中之前創(chuàng)建的對象來初始化新創(chuàng)建的對象痹栖。如果在類中沒有定義拷貝構造函數(shù)亿汞,編譯器會自行定義一個【景ⅲ拷貝構造函數(shù)通常用于:
- 通過使用另一個同類型的對象來初始化新創(chuàng)建的對象疗我。
- 復制對象把它作為參數(shù)傳遞給函數(shù)。
- 復制對象南捂,并從函數(shù)返回這個對象吴裤。
如果類帶有指針變量,并有動態(tài)內存分配溺健,則它必須有一個拷貝構造函數(shù)麦牺。拷貝構造函數(shù)的最常見形式如下:
classname (const classname &obj) {
// 構造函數(shù)的主體
}
C++ 友元函數(shù)
類的友元函數(shù)是定義在類外部鞭缭,但有權訪問類的所有私有(private)成員和保護(protected)成員剖膳。
盡管友元函數(shù)的原型有在類的定義中出現(xiàn)過,但是友元函數(shù)并不是成員函數(shù)缚去。
友元可以是一個函數(shù)潮秘,該函數(shù)被稱為友元函數(shù)琼开;友元也可以是一個類易结,該類被稱為友元類,在這種情況下柜候,整個類及其所有成員都是友元搞动。
#include <iostream>
using namespace std;
class Box
{
double width;
public:
friend void printWidth( Box box );
void setWidth( double wid );
};
// 成員函數(shù)定義
void Box::setWidth( double wid )
{
width = wid;
}
// 請注意:printWidth() 不是任何類的成員函數(shù)
void printWidth( Box box )
{
/* 因為 printWidth() 是 Box 的友元,它可以直接訪問該類的任何成員 */
cout << "Width of box : " << box.width <<endl;
}
// 程序的主函數(shù)
int main( )
{
Box box;
// 使用成員函數(shù)設置寬度
box.setWidth(10.0);
// 使用友元函數(shù)輸出寬度
printWidth( box );
return 0;
}
C++ 內聯(lián)函數(shù)inline
C++ 內聯(lián)函數(shù)是通常與類一起使用渣刷。引入內聯(lián)函數(shù)的目的是為了解決程序中函數(shù)調用的效率問題鹦肿。如果一個函數(shù)是內聯(lián)的,那么在編譯時辅柴,編譯器會把該函數(shù)的代碼副本放置在每個調用該函數(shù)的地方箩溃。內聯(lián)函數(shù)的定義只能是一行(編譯器能正確的替換)瞭吃。
C++ 類的靜態(tài)成員
使用 static 關鍵字來把類成員定義為靜態(tài)的,當聲明類的成員為靜態(tài)時涣旨,這意味著無論創(chuàng)建多少個類的對象歪架,靜態(tài)成員都只有一個副本,在創(chuàng)建第一個對象時霹陡,所有的靜態(tài)數(shù)據(jù)都會被初始化為零和蚪。
不能把靜態(tài)成員的初始化放置在類的定義中,但是可以在類的外部通過使用范圍解析運算符:: 來重新聲明靜態(tài)變量從而對它進行初始化烹棉。靜態(tài)成員函數(shù)即使在類對象不存在的情況下也能被調用攒霹,靜態(tài)函數(shù)只要使用類名加范圍解析運算符 :: 就可以訪問。
// 初始化類 Box 的靜態(tài)成員
int Box::objectCount = 0;
靜態(tài)成員函數(shù)與普通成員函數(shù)的區(qū)別:
- 靜態(tài)成員函數(shù)沒有 this 指針浆洗,只能訪問靜態(tài)成員(包括靜態(tài)成員變量和靜態(tài)成員函數(shù))催束。
2. C++ 繼承
class derived-class: access-specifier base-class, base-class
C++ 重載運算符和重載函數(shù)
C++ 允許在同一作用域中的某個函數(shù)和運算符指定多個定義,分別稱為函數(shù)重載和運算符重載
//重載‘+’運算符伏社,可以把 operator+ 當做函數(shù)名
Box operator+(const Box&);
Box operator+(const Box&, const Box&);
3. 多態(tài)
不同于 java泣崩,直接重寫父類的同名函數(shù),子類對象調用同名函數(shù)時被編譯器設置為基類中的版本洛口,這就是所謂的靜態(tài)多態(tài)矫付,或靜態(tài)鏈接 - 函數(shù)調用在程序執(zhí)行前就準備好了。有時候這也被稱為早綁定第焰,因為函數(shù)在程序編譯期間就已經設置好了买优。
虛函數(shù)
虛函數(shù) 是在基類中使用關鍵字 virtual 聲明的函數(shù)。在派生類中重新定義基類中定義的虛函數(shù)時挺举,會告訴編譯器不要靜態(tài)鏈接到該函數(shù)杀赢。這種操作被稱為動態(tài)鏈接,或后期綁定湘纵。
純虛函數(shù)
可以在基類中聲明一個虛函數(shù)脂崔,以便在派生類中重新定義該函數(shù)更好地適用于對象,基類中又不對虛函數(shù)給出有意義的實現(xiàn)梧喷,這個時候就會用到純虛函數(shù)砌左。
class Shape {
protected:
int width, height;
public:
Shape( int a=0, int b=0)
{
width = a;
height = b;
}
// pure virtual function
virtual int area() = 0;//= 0 告訴編譯器,函數(shù)沒有主體铺敌,上面的虛函數(shù)是純虛函數(shù)汇歹。
};
C++ 接口(抽象類)
c++沒有特定的關鍵字定義接口(抽象類)
C++ 接口是使用抽象類來實現(xiàn)的,如果類中至少有一個函數(shù)被聲明為純虛函數(shù)偿凭,則這個類就是抽象類产弹。純虛函數(shù)是通過在聲明中使用 "= 0" 來指定的。抽象類不能被用于實例化對象弯囊,它只能作為接口使用痰哨。如果試圖實例化一個抽象類的對象胶果,會導致編譯錯誤。