類
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、調用類的靜态成員函數時,可以用::
寵辱不驚,看庭前花開花落;去留無意,望天上雲卷雲舒