c++程式設計中經常出現兩個不同的類物件之間相互訪問資料的需要,但是成員變數不是public形式,無法直接訪問相應的變數,拋開全域性變數不談,常用的方法有:1類封裝留下的介面函式、2友元機制、3類靜態成員變數。
回顧:類是物件導向程式設計語言中的乙個概念。類是對某個物件定義,它含有有關物件的動作方式的資訊,包括他的名稱,方法,屬性和事件
類成員有3種不同的訪問許可權 1
公有(public)
成員可以在類外訪問
2私有(private)
成員只能在累的成員函式之間進行訪問
3保護(protected)
只能在類的成員以及派生類的成員函式之間
簡單理解封裝和介面介面,簡單說就是public的方法,供外部使用,通過這些public的方法,可以操作內部資料,所以稱之為介面。 封裝,乙個類是由資料與方法組成的,將資料和方法放在一起,就是封裝。
知識點補充:
i).建構函式後面的冒號就是初始化,而括號裡面的等於號並不是初始化,而是變數生成以後的賦值而已(永遠都是2個步驟)
ii)作用域符號 :: 的前面一般是類名稱,後面一般是該類的成員名稱,c++為例避免不同的類有名稱相同的成員而採用作用域的方式進行區分
如:a,b表示兩個類,在a,b中都有成員member。那麼 a::member就表示類a中的成員member b::member就表示類b中的成員member
iii)全域性作用域符號:當全域性變數在區域性函式中與其中某個變數重名,那麼就可以用 :: 來區分如:
char zhou; //全域性變數
void sleep()
char zhou; //區域性變數
char(區域性變數) = char(區域性變數) *char(區域性變數) ;
::char(全域性變數) =::char(全域性變數) *char(區域性變數);
iv):: 是c++裡的「作用域分解運算子」。
比如宣告了乙個類a,類a裡宣告了乙個成員函式voidf(),但沒有在類的宣告裡給出f的定義,那麼在類外定義f時,就要寫成voida::f(),表示這個f()函式是類a的成員函式。例如
class
ca ;
//那麼在實現這個函式時,必須這樣書寫:
int
ca::add(
int
a,
int
b)
//另外,雙冒號也常常用於在類變數內部作為當前類例項的元素進行表示,比如:
int
ca::add(
int
a)
//表示當前類例項中的變數ca_var。
由於我們不想暴露aimpl.h中,故對其封裝,即在a.h和a.cpp中對其包一層。
我們甚至在a.h中都不需要宣告 aimpl *imp_的,在a.h中可以只宣告乙個void *imp_,在a.cpp中將該void *指標轉換成almpl *即可。
aimpl.h
class aimpl
;
a,h
class aimpl;
class a
;
a.cpp
#include "aimpl.h"
#include "a.h"
a::a()
: imp_(new aimpl)
a::~a()
void a::f()
2.父類宣告為虛函式
下面通過乙個具體的例項進行介面的是實現。
//實現
ibase::ibase()
ibase::~ibase()
ibase *create()
main,cpp
using namespace std;
int main()
return 0;
}在乙個類中,可以利用關鍵字friend將別的模組(一般函式、其他類的成員函式或其他類)宣告為它的友元,這樣這個類中本來隱藏的資訊就可以被友元訪問j。如果友元是一般函式或類的成員函式,稱為友元函式;如果友元是乙個類,則稱為友元類,友元類的所有成員函式都成為友元函式。
class b
;在b類宣告f函式為友元函式,則在f函式中通過物件名可直接訪問b類所有的資料成員。同時在b類宣告a類為友元類,則a類的所有成員函式都是b類的友元函式,都可以訪問b類的私有和保護成員。採用友元類共享資料機制,使友元類成員函式可以通過物件名直接訪問到隱藏的資料,從而使程式達到高效協調工作。在較為複雜的問題中,實現不同類之間的資料共享,友元類的使用也是必不可少的選擇。友元在類之間、類與普通函式之間共享了內部封裝的資料的同時,必然會對類的封裝性帶來一定的破壞。因此在程式設計中使用友元,要在共享和封裝之間找到乙個恰當的平衡點,從而達到提高程式效率同時,將程式隱患降來最低。
c++中使用靜態成員可以實現同一類的不同物件之間共享資料 j。類的普通資料成員在類的每乙個物件都有乙個拷貝,就是說每個物件的同名資料成員可以分別儲存不同數值,這就保證物件擁有自身區別其他物件的特徵的需要。靜態資料成員是類的資料成員的一種特例,採用static關鍵字來宣告;每個類只有乙個拷貝,由該類的所有物件共同維護和使用,從而實現了同一類的不同物件之間的資料共享。
例如:#include
using namespace std;
class sample
sample(sample & s)
void show(void)
void input(void)
};char sample::m_sarray[10] = "i am a engineer";
int main(void)
//執行結果如下:
default constructor!
i am a engineer
copy constructor!
i am a engineer
this is my job
this is my job
靜態成員變數m_sarray確實起到了在不同物件間共享的作用!不過由於其是靜態屬性,記憶體是在全域性/靜態區域開闢的,屬於棧記憶體區,記憶體大小使用受限。如果能動態從堆中申請記憶體,則可以使用大記憶體空間了。
有一學生類:
class engineer
如果程式中需要統計學生人數,這個資料存放在什麼地方呢?若以類外的全域性變數來存放,不能實現資料的隱藏,若在類中增加乙個資料成員用以存放人數,必然在每乙個物件中都儲存一副本,這樣不僅冗餘,而且每個物件分別維護乙個「人數」,勢必造成資料的不一致性。因此,比較好的方案是在engineer類中增加乙個靜態資料成員。static count用來存放學生「人數」。
C語言中不同型別資料之間的賦值
整數與整數之間 一 長度相等 在記憶體中儲存的位數相等 的兩個不同的型別的資料之間的賦值 在計算機中的儲存內容不變,只是資料按照不同的編碼格式來解析。二 長賦值給短 短 長 擷取低位,然後按照短整數的資料型別解析。三 短賦值給長 長 短 其中,短轉長又分為三種情況 1.兩個資料都是無符號的資料,短整...
不同型別陣列之間的資料拷貝
工作中,需要將乙個float型別的陣列整體copy到乙個double型別的陣列中。很顯然,memcpy是不行的,因為float和double占用的位元組數不一樣。本來打算用for迴圈乙個乙個元素賦值,但這方法肯定特慢,效率差。不死心,查一查,原來std copy能夠搞定這個問題。舉例說明 doubl...
List中存放不同型別物件之間的轉換
有時候我們會碰到這種問題 兩個list中存放的物件不一樣,但是大部分的屬性相同,想把其中乙個list中的物件加上別的屬性之後變成另乙個list中的物件,例如 listlist req.getnafmiimemberinfo listtemplist new arraylist 把得到的資料轉換成要匯...