2015-10-21 226 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**/ 
}