Friend

你沒有朋友(我也沒有)

Friend Function 介紹

我們不能從該Class的外部access該Class的private members。
但是,如果將non member function聲明為class的friend,我們就可以使其access該class的private member。

這是通過在Class中包含此外部function的聲明並在其前面加上關鍵字friend來實現的。

Syntax :

1
friend return_type function_name(parameters);

Friend Function(Pass by Reference)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class MyClass {
public:
MyClass() {
regVar = 0;
}
private:
int regVar;

//Allow someFunc() to access private member of class MyClass
friend void someFunc(MyClass &obj); //Pass by reference
//Note that when passing an object to the function,
//we need to pass it by reference
//using the & operator.
};

//The function someFunc() is defined as a regular function outside the class.
//It takes an object of type MyClass as its parameter,
//and is able to access the private data members of that object.
void someFunc(MyClass &obj) {
obj.regVar = 42;
cout << obj.regVar;
}

int main() {
MyClass obj;
someFunc(obj);
}

//Outputs 42

請注意,將Object傳遞給function時,我們需要使用運算符通過reference將其傳遞(Pass by reference)。因此,我們可以使用實際對象,而不是對象的copy(副本)。 如果不用的話,我們是Pass by value(通過值傳遞),創建對象的副本。

Friend Function(Pass by value)

如果用 Pass by value呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
using namespace std;
class XYZ {
private:
int num=100;
char ch='Z';
public:
friend void disp(XYZ obj); //Pass by value
};
//Global Function
void disp(XYZ obj){
cout<<obj.num<<endl;
cout<<obj.ch<<endl;
}
int main() {
XYZ obj;
disp(obj);
return 0;

//output:
//100
//Z
}

friend的用法就是在兩個不同Class之間進行的操作,它們訪問兩者的private member。

而且您可以在任意多個Class中聲明一個friend function。

實例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
using namespace std;
// forward declaration
class B;
class A {
private:
int numA;
public:
A(): numA(12) { }
// friend function declaration
friend int add(A, B);
};
class B {
private:
int numB;
public:
B(): numB(1) { }
// friend function declaration
friend int add(A , B);
};
// Function add() is the friend function of classes A and B
// that accesses the member variables numA and numB
int add(A objectA, B objectB)
{
return (objectA.numA + objectB.numB);
}
int main()
{
A objectA;
B objectB;
cout<<"Sum: "<< add(objectA, objectB);
return 0;

//Sum: 13
}

Friend Class

您可以定義一個friend class,讓這個friend class access其他class的private member。當一個class成為friend class時,該class的所有member functions都將成為friend functions。

在此示例中,我們有兩個Class - XYZABCXYZ Class具有兩個private member chnum,該類將ABC聲明為friend class。 這意味著ABC可以訪問XYZ的private member ,在ABC class的function disp()access private member numch的示例中已經證明了這一點。

在此示例中,我們是用Pass by value。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
using namespace std;
class XYZ {
private:
char ch='A';
int num = 11;
public:
/* This statement would make class ABC
* a friend class of XYZ, this means that
* ABC can access the private and protected
* members of XYZ class.
*/
friend class ABC;
};
class ABC {
public:
void disp(XYZ obj){
cout<<obj.ch<<endl;
cout<<obj.num<<endl;
}
};
int main() {
ABC obj;
XYZ obj2;
obj.disp(obj2);
return 0;

//output :
//A
//11
}

This

C++中的每個Object都可以通過稱為this pointer來訪問其自己的address(地址)。
在member function中,this指 refer to the invoking object。

friend function沒有this pointer,因為friends不是class的member。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class MyClass {
public:
MyClass(int a) : var(a)
{ }
void printInfo() {
//All three alternatives will produce the same result.
cout << var<<endl;
cout << this->var<<endl; //this is a pointer to the object, so the arrow selection operator is used to select the member variable.
cout << (*this).var<<endl;
}
private:
int var;
};

int main() {
MyClass obj(42);
obj.printInfo();
}

/* Outputs
42
42
42
*/

注意,只有member function具有this指針。

this關鍵字在operator overloading中有著重要的作用(其實不太重要)。

Reference

C++ friend Function and friend Classes
Friend Class and Friend Functions in C++