2015-10-21 53 views
1

我的代碼: -函數如何訪問類對象的私有數據成員?

#include<iostream> 
using namespace std; 

class a{ 
    private: 
     int x; 
    public: 
     a(int data) 
     { 
     x=data; 
     } 
     friend void printPrivateMember(a); 
}; 

void printPrivateMember(a obj) 
{ 
    cout<<obj.x; //I can access private data member by an object inside this function. 
} 

int main() 
{ 
    a obj1(5); 
    printPrivateMember(obj1); 
    cout<<obj1.x; //this gives error 
    return 0; 
} 

我想知道,以我怎麼可以用一個對象在友元函數訪問私有數據類型,但在主不能這樣做。

當我閱讀有關訪問說明符。它指定private可以只被成員函數訪問(我對friend函數沒有問題),而不是該類的對象。我想知道有什麼區別,因爲我可以通過一個對象訪問私人成員,而在另一個案例中不能這樣做。這同樣適用於複製構造函數。

+0

您可以使用朋友功能概念。 –

回答

1

這正是朋友功能的作用:任何一個班級的朋友功能都可以訪問它的私人成員。由於您的printPrivateMember被宣告爲a的好友,因此可以訪問它的私人x成員。由於main不是朋友功能,它不能。

遏制關於宣佈main爲朋友的問題,this question涵蓋它。

+0

我想知道我們如何通過類的對象訪問私有成員。我們不需要一個成員函數來訪問它們嗎? – Echo

+0

@SudeshnaBora,不,你可以直接從任何地方訪問它們,如果它們是公開的,即使這些成員不公開,也可以來自朋友功能或朋友類。 – SingerOfTheFall

+0

@SudeshnaBora是的,你需要一個成員函數**或**一個'朋友'。但這只是您在示例程序中觀察到的行爲。 – Downvoter

0

正如你所看到的,只有成員函數(包括構造函數和析構函數)和函數和類可以訪問你的private。這就是friend s的用途:它們向封裝機制提供了一個例外(而不是std::exception)。

現在你可以考慮這是破壞封裝還是實際上穩定它。

1

因爲朋友可以這樣做。

$11/1 Member access control [class.access]

(重點煤礦)

1一類的成員可以是

(1.1) - 私人;也就是說,其名稱可以是 ,只有會員使用,類別的朋友,其中 已聲明。
(1.2) - 受保護;也就是說,它的名字只能由 成員和其聲明的班級的朋友,由該班級派生的班級 以及他們的朋友(見11.4)使用。
(1.3) - public;也就是說,它的名字可以在任何地方使用,而無需訪問 限制。

0

,如果你想訪問私有成員,你最好使用公共功能,如:

class a { 
private: 
    int m; 
public: 
    int getM() { 
    return m; 
    } 
}; 
0

您使用短語不是由該類的對象讓我覺得你對訪問規則不清楚。訪問規則不適用於對象,但可以訪問對象的成員變量和成員函數。

一個類的成員變量可以在一個函數中被訪問 - 它可以是該類的成員函數,另一個類的成員函數或全局函數。

它也可以在全球空間訪問,例如,初始化一個全局變量。

一個friend聲明一個類的變化,通過使用privateprotectedpublic訪問說明到位的默認訪問規則。

一個聲明爲friend的函數可以訪問類的所有實例的所有成員。

answer by songyuanyao引用了提供有關該主題的更多詳細信息的標準部分。

+0

我想知道如何通過friend函數中的類(obj)的對象訪問x(數據成員)。但主要不能這樣做。我假定對象只能通過成員函數直接訪問私有成員。 – Echo

+0

這很簡單。當你將一個函數聲明爲一個類的「朋友」時,就是這樣。由於'main'沒有被聲明爲類的'friend',所以你只能在'main'中訪問'public'成員變量和類的成員函數。 –

+0

所以成員訪問與類的對象無關。我不知道如何得到這個奇怪的概念。非常感謝。 – Echo

0

此功能應該是公開的,以便您可以通過main()訪問它。

void print(){ 
    /**print or return your private variable here**/ 
}