嵌入式C++開發詳解(二)
面向物件程式設計(一)
一、面向物件程式設計介紹
(一)什麼是面向物件?
面向將系統看成通過互動作用來完成特定功能的物件的集合。每個物件用自己的方法來管理資料。也就是說只有物件內部的程式碼能夠操作物件內部的資料。
(二)面向物件的優點
·面向過程的缺點
不容易維護,靈活性差,不容易擴充套件,更談不上覆用,由於客戶的需求多變,導致程式設計師加班加點,甚至整個專案經常返工。
·面向物件的優點
通過繼承、封裝、多型降低程式的耦合度,並結合設計模式讓程式更容易修改和擴充套件,並且容易複用。
(三)面向物件的特點
抽象、封裝、繼承、多型
1.抽象:
·抽象是人們認識事物的一種方法
·抓住事物本質,而不是內部具體細節或者具體實現
2.封裝
·封裝是指按照資訊遮蔽的原則,把物件的屬性和操作結合一起,構成獨立的物件。
·通過限制對屬性和操作的訪問許可權,可以將屬性“隱藏”在物件內部,對外提供一定的介面,在物件之外只能通過介面對物件進行操作。
·封裝性增加了物件的獨立性,從而保證資料的可靠性。
·外部物件不能直接對操作物件的屬性,只能使用物件提供的服務。
3.繼承
·繼承表達了對物件的一般與特殊的關係。特殊類的物件具有一般類的全部屬性和服務。
·當定義了一個類後,又需定義一個新類,這個新類與原來的類相比,只是增加或修改了部分屬性和操作,這時可以用原來的類派生出新類,新類中只需描述自己所特有的屬性和操作。
·繼承性大大簡化了對問題的描述,大大提高了程式的可重用性,從而提高了程式設計、修改、擴充的效率等。
4.多型
·多型性:同一個訊息被不同物件接收時,產生不同結果,即實現同一介面,不同方法。
·一般類中定義的屬性和服務,在特殊類中不改變其名字,但通過各自不同的實現後,可以具有不同的資料型別或者具有不同的行為。
當向圖形物件傳送訊息進行繪圖服務請求後,圖形物件會自動判斷自己的所屬類然後執行相應的繪圖服務。
總結:面向物件程式設計的優缺點
面向物件程式設計的優點:
·易維護:可讀性高,即使改變需求,由於繼承的存在,維護也只是在區域性模組,維護起來是非常方便和較低成本的。
·質量高:可重用現有的,在以前的專案的領域中已被測試過的類使系統滿足業務需求並具有較高質量。
·效率高:在軟體開發時,根據設計的需要對現實世界的事物進行抽象,產生類。這樣的方法解決問題,接近於日常生活和自然的思考方式,勢必提高軟體開發的效率和質量
·易擴充套件:由於繼承、封裝、多型的特性,自然設計出高內聚、低耦合的系統結構,使得系統更靈活、更容易擴充套件,而且成本較低。
面向物件程式設計的缺點:
執行效率會下降10%左右
二、類與物件
(一)類的宣告
//類是一種使用者自定義型別,宣告形式:
class 類名稱
{
public:
公有成員(外部介面)
private:
私有成員
protected:
保護成員
};
例:
#include <iostream>
using namespace std;
class Test
{
public:
int x_;
protected:
int y_;
private:
int z_;
};
int main()
{
Test t;
t.x_ = 5;
t.y_ = 6; //Error!不可訪問
t.z_ = 7; //Error1不可訪問
cout << "t.x: " << t.x_ << endl;
return 0;
}
升級版:
#include <iostream>
using namespace std;
class Test
{
public:
int x_;
void setX(int x)
{
x_ = x;
}
void setY(int y)
{
y_ = y;
}
void setZ(int z)
{
z_ = z;
}
int getX()
{
return x_;
}
int getY()
{
return y_;
}
int getZ()
{
return z_;
}
protected:
int y_;
private:
int z_;
};
int main()
{
Test t;
t.x_ = 5;
cout << "t.x: " << t.x_ << endl;
cout << "t.y: " << t.getY() << endl;
cout << "t.z: " << t.getZ() << endl;
return 0;
}
編譯結果:
PS:y,z未進行初始化所以是亂碼。
(二)public、private、protected
·在關鍵字public後面宣告,它們是類與外部的介面,外部函式都可以訪問公有型別資料和函式。
·在關鍵詞private後面宣告,只允許本類中的函式訪問,而類外部的任何函式都不能訪問。
·在關鍵詞protected後面宣告,與private類似,其差別表現在繼承與派生時對派生類的影響不同。
(三)成員函式
1.類內實現成員函式
函式類內實現預設為inline函式,佔用空間,所有一般類外實現函式
上述例題中函式為類內實現
2.類外實現成員函式
例:
Test.h
#ifndef _TEST_H_
#define _TEST_H_
class Test
{
public:
int x_;
void initXYZ(int x, int y, int z);
void display();
protected:
int y_;
private:
int z_;
};
#endif
Test.c:
#include "Test.h"
#include <iostream>
using namespace std;
void Test::initXYZ(int x, int y, int z)
{
x_ = z;
y_ = y;
z_ = x;
}
void Test::display()
{
cout << "x:" << x_ << "\t" << "y:" << y_ << "\t" << "x:" << z_ << "\t" << endl;
}
lei.c:
#include <iostream>
#include "Test.h"
using namespace std;
int main()
{
Test t;
t.initXYZ(1, 2, 3);
t.display();
return 0;
}
執行結果:
3.成員函式的過載及預設引數
(四)class VS struct
class資料成員預設私有
struct資料成員預設公有
例:
#include <iostream>
using namespace std;
class Test
{
public:
int x_;
int y_;
int z_;
};
struct Test1
{
int x_;
int y_;
int z_;
void initXYZ(int x, int y, int z)
{
x_ = x;
y_ = y;
z_ = z;
}
};
int main()
{
Test t1;
t1.x_ = 5;
Test1 t2;
t2.initXYZ(1, 2, 3);
cout << "t1:" << t1.x_ << endl;
cout << "t2:" << t2.x_ << endl;
cout << sizeof(t1) << endl;
cout << sizeof(t2) << endl;
return 0;
}
執行結果:
C++編譯器對struct升級:
在結構體內可以加入函式
由執行結果可知:
·類的大小與成員函式無關,只與成員有關
·對齊方式與大小與結構體一樣
·物件的大小由成員決定
·方法是共享的
(五)物件的儲存型別
程式碼驗證:
#include <iostream>
using namespace std;
class Test
{
private:
int x_;
int y_;
int z_;
public:
void initXYZ(int x, int y, int z)
{
this->x_ = x;
this->y_ = y;
this->z_ = z;
}
};
int main()
{
Test *t1 = new Test();
t1->initXYZ(1, 2, 4);
return 0;
}
除錯結果:
(六)類的作用域
前向宣告:只能定義指標或者引用,不能有另一個類的物件
程式碼示例:
A.h
#ifndef _A_H_
#define _A_H_
class B;//前向宣告
class A
{
public:
A();
~A();
private:
B *b; //B &b
};
#endif
B.h
#ifndef _B_H_
#define _B_H_
class B
{
public:
B();
~B();
};
#endif
A.cpp
#include "A.h"
#include <iostream>
using namespace std;
A::A()
{
cout << "init A!" << endl;
}
A::~A()
{
cout << "destory A!" << endl;
}
B.cpp
#include "B.h"
#include <iostream>
using namespace std;
B::B()
{
cout << "init B!" << endl;
}
B :: ~B()
{
cout << "destory B!" << endl;
}
main.c
#include <iostream>
#include "A.h"
#include "B.h"
int main()
{
return 0;
}
編譯結果:
(七)巢狀類(內部類)
·從作用域的角度看,巢狀類被隱藏在外圍類中,該類名只能在外圍類中使用。如果
在外圍類的作用域使用該類名時,需要加名字限定
·巢狀類中的成員函式可以在它的類體外定義
·巢狀類的成員函式對外圍類的成員沒有訪問權,反之亦然。
·巢狀類僅僅只是語法上的嵌入
(八)區域性類
·類也可以定義在函式體內,這樣的類被稱為區域性類(local class)。局
部類只在定義它的區域性域內可見
·區域性類的成員函式必須被定義在類體中。
·區域性類中不能有靜態成員
程式碼示例:
#include <iostream>
using namespace std;
class Test
{
public:
int x_;
class Inner //巢狀類
{
public:
int num;
void func();
};
void setX(int x)
{
x_ = x;
display();
}
void setY(int y)
{
y_ = y;
display();
}
void setZ(int z)
{
z_ = z;
}
int getX()
{
return x_;
}
int getY()
{
return y_;
}
int getZ()
{
return z_;
}
protected:
int y_;
void display()
{
cout << x_ << y_ << z_ << endl;
}
private:
int z_;
};
void Test::Inner::func()
{
cout << "hello world" << endl;
}
int main()
{
class LocalClass //區域性類
{
void func()
{
}
}
Test t;
Test::Inner n;
t.x_ = 6;
t.setY(6);
t.setZ(7);
cout << "t.y_ = " << t.getY() << endl;
cout << "t.z_ = " << t.getZ() << endl;
cout << "t.x_ = " << t.x_ << endl;
return 0;
}