C++ friend and operator overloading

Tomomoto:

After adopting the class mechanism, the data hiding and encapsulation are realized. The data members of the class are generally defined as private members, and the member functions are generally defined as public, so as to provide the communication interface between the class and the outside world. However, sometimes you need to define some functions, which are not part of the class, but need to frequently access the data members of the class, then you can define these functions as friend functions of the function. In addition to friend functions, there are also friend classes, which are collectively called friends. The role of friends is to improve the running efficiency of the program (that is, to reduce the time overhead required for type checking and security checking, etc.), but it destroys the encapsulation and hiding of the class, allowing non-member functions to access private members of the class .

Friend function:

 Friend functions are non-member functions that can directly access private members of a class. It is an ordinary function defined outside the class. It does not belong to any class, but it needs to be declared in the class definition. When declaring, you only need to add the keyword friend before the name of the friend. The format is as follows: friend type function
       name (formal parameters);

       The declaration of a friend function can be placed in the private part of the class, or it can be placed in the public part. There is no difference between them, and they all indicate that they are a friend function of the class.
       A function can be a friend function of multiple classes, and only needs to be declared separately in each class.
       The method and principle of calling a friend function is consistent with that of a general function.

eg:

main function:

// youyuan.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "UncleWang.h"
#include "Family.h"

void GetUncle_Heart(const UncleWang& uncle);


int _tmain(int argc, _TCHAR* argv[])
{
	UncleWang uncle1;
	uncle1.Hobby();
	GetUncle_Heart(uncle1);
	getchar();

	return 0;
}

void GetUncle_Heart(const UncleWang& uncle)
{
	cout << "要俘获的人的心的名:" << uncle.name  << endl;
	cout << "要俘获的人的心的龄:" << uncle.age  << endl;
}



 #include "UncleWang.h"

#pragma once
#define NAMELEN 10
class UncleWang
{
	char* name;
	int age;
public:
	UncleWang();
	void Hobby();
	friend void GetUncle_Heart(const UncleWang& uncle);
	~UncleWang();
};

UncleWang.cpp

#include "stdafx.h"
#include "UncleWang.h"


void UncleWang::Hobby()
{
	cout << "我是隔壁" << this->name << ",我的年龄是:" << this->age << endl;
}

UncleWang::UncleWang()
{
	this->name = new char[NAMELEN];
	memset(this->name,0,NAMELEN);
	strcpy(this->name,"老王");
	this->age = 35;

}


UncleWang::~UncleWang()
{
	delete[] name;
}

This is the friend function.

Friend class:

  All member functions of a friend class are friend functions of another class and can access hidden information (including private members and protected members) in another class.       
       When you want a class to be able to access the private members of another class, you can declare the class as a friend class of another class. The statement format for defining a friend class is as follows:
       friend class class name;
       where: friend and class are keywords, and the class name must be a defined class in the program.

       For example, the following statement shows that class B is a friend class of class A:
       class A
       {               ...        public:               friend class B;               ...        };        After the above description, all member functions of class B are friend functions of class A, which can save Get the private and protected members of class A.





       Note when using friend class:
             (1) Friend relationship cannot be inherited.
             (2) The friendship relationship is one-way and not exchangeable. If class B is a friend of class A, class A is not necessarily a friend of class B, depending on whether there is a corresponding statement in the class.
             (3) The friendship relationship is not transitive. If class B is a friend of class A, class C is a friend of B, class C is not necessarily a friend of class A, it also depends on whether there is a corresponding declaration in the class

After A is declared as a friend class by B, in the function of A, if B is a parameter, members and member functions of B can be directly accessed.

example:

main.cpp

// youyuan.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "UncleWang.h"
#include "Family.h"

void GetUncle_Heart(const UncleWang& uncle);


int _tmain(int argc, _TCHAR* argv[])
{
	UncleWang uncle1;
	//uncle1.Hobby();
	//GetUncle_Heart(uncle1);
	Family f;
	uncle1.Uncle_visit_Family(f);
	getchar();

	return 0;
}

void GetUncle_Heart(const UncleWang& uncle)
{
	cout << "要俘获的人的心的名:" << uncle.name  << endl;
	cout << "要俘获的人的心的龄:" << uncle.age  << endl;
}



family.h

#pragma once
#define NAMELEN 10
class Family
{
	char* mother;
	char* father;
	char* me;
public:
	friend class UncleWang;
	Family();
	~Family();
	void Show();
};

family.cpp

#include "stdafx.h"
#include "Family.h"

void Family::Show()
{
	cout << "家庭成员:" << this->father<<" " << this->mother<<" " << this->me;
}

Family::Family()
{
	this->father = new char[NAMELEN];
	this->mother = new char[NAMELEN];
	this->me = new char[NAMELEN];
	strcpy(this->father,"父亲");
	strcpy(this->mother, "母亲");
	strcpy(this->me, "我");
}


Family::~Family()
{
	delete[] father;
}

 UncleWang.h

#pragma once
#define NAMELEN 10
#include "Family.h"
class UncleWang
{
	char* name;
	int age;
public:
	UncleWang();
	void Hobby();
	friend void GetUncle_Heart(const UncleWang& uncle);
	void Uncle_visit_Family(Family uncle);
	~UncleWang();
};

  UncleWang.cpp

#include "stdafx.h"
#include "UncleWang.h"


void UncleWang::Hobby()
{
	cout << "我是隔壁" << this->name << ",我的年龄是:" << this->age << endl;
}

void UncleWang::Uncle_visit_Family(Family f)
{
	cout << this->name << "拜访了" <<f.father << "一家"<<endl;
	cout << "f的一家:";
	f.Show();
}

UncleWang::UncleWang()
{
	this->name = new char[NAMELEN];
	memset(this->name,0,NAMELEN);
	strcpy(this->name,"老王");
	this->age = 35;

}


UncleWang::~UncleWang()
{
	delete[] name;
}

Operator overloading:

The essence of operator overloading is function overloading, but there are certain rules to follow.

Binary operators should be declared as friends as much as possible and written outside the class. cin cout must be declared as a friend.

The first point:

What we must pay attention to here is that the number of overloaded parameters must be consistent with the original number of operators. For example, the parameters of the + sign are two left addends and right addends. Then when we overload the plus sign, we must also ensure that there are two addends on the left and right as parameters.

Second point:

When overloading as a normal function:

Monocular: the right operand is the formal parameter; binocular: the left formal parameter is the left operand of the operator, and the right formal parameter is the right operand.

When overloading as a member function of a class:

If there is only one operator parameter, then there is no need to write the parameter; if there are two operator parameters, then only one parameter needs to be written.

Because the member function of the class has a this pointer by default. It will point directly to the class itself. In other words, when we write operator overloading, one of the parameters is already contained by the this pointer.

Unary operator, this points to the right parameter of the operator, because the parameters of the unary operator are generally on the right.

Binary operator, this points to the left parameter of the operator.

Take the minus sign as an example, when two time classes a and b are subtracted. If it is a - b, then the this pointer points to a, otherwise it points to b. When declaring a function, we only need to write the right parameter. For a - b, you only need to write int operator-(Time b);

Of course, since the unary operator has only one parameter, and the parameter is pointed to by this, then we don't need to declare any parameters.

(2). Return value
The return value type of the operator depends on the function of the overloaded function.

For example, the function of a + b is to get an addend, then the return value is the value of a+b. The function of a += b is to change the value of a. Since the value of parameter a is changed, there is no need to return a value.

Also, if we need operators to support multiple operations, we also need to return values. For example, the stream insertion operator <<. We may need to insert multiple times, like cout << a << b << c; we need to return the stream ostream itself to facilitate subsequent stream insertion.

The << >> operator is overloaded:

#include <iostream>
#include <string> 
#include <cstring> 
using namespace std;
class String
{
private:
    string str;   
public:
	String(string s){str=s;}
	char & operator[](int i);
	friend ostream & operator<<(ostream & cout, const String & st);
    friend istream & operator>>(istream & cin, String & st);
};

char &String::operator[](int i)
{
    return str[i];
}
ostream &operator<<(ostream & cout, const String &st)
{
    cout << st.str;
    return cout;
}

istream &operator>>(istream & cin, String &st)
{
    char temp[40];
    is.get(temp, 40);
    if (cin)
        st = temp;
    while (cin && cin.get() != '\n')
        continue;
    return cin;
}

 = operator overloading

#include <cstring>
#include <sstream>
class HugeInteger{
public:
	HugeInteger& operator=(const HugeInteger &h);
private:
    string str;
};

HugeInteger& HugeInteger::operator=(const HugeInteger &h)
{
    this->str=h.str;
    return *this;
}

Guess you like

Origin blog.csdn.net/makabaka12138/article/details/128538129