C 不同類物件之間訪問資料的3種簡單常用方法

2021-09-25 15:09:01 字數 4262 閱讀 7995

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的成員函式。例如

classca ;

//那麼在實現這個函式時,必須這樣書寫:

intca::add(inta,intb)

//另外,雙冒號也常常用於在類變數內部作為當前類例項的元素進行表示,比如:

intca::add(inta)

//表示當前類例項中的變數ca_var。

1.對原功能的**在打包一層

由於我們不想暴露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 把得到的資料轉換成要匯...