Modifiers, friends and operator overloading

1.Modifier

In C++, all member variables and member functions have access rights. The so-called access rights refer to whether you can access the member variables and member functions in the class.

In C++, the keywords used to control access permissions are public, protected, and private, which represent public, protected, and private respectively. At the same time, they are collectively called member access qualifiers.

public
It can be accessed by functions in the class, functions of subclasses, and its friend functions, and can also be accessed by objects of the class.

protected
It can be accessed by functions in this class, functions of subclasses, and its friend functions, but it cannot be accessed by objects of this class.

private
Can only be accessed by functions in the class, its friend functions, and cannot be accessed by anything else, nor by objects of the class

class Student {
public:
int v1 = 100;
private:
int v2 = 200;
protected:
int v3 = 300;
public:
void func1() {
cout << v1 << endl;
cout << v2 << endl;
cout << v3 << endl;
}
};
int main() {
Student s1;
s1.func1();
s1.v1 = 99;
//s1.v2 = 11; //Object cannot access private properties
//s1.v3 = 33; //Object cannot access protected properties
return 0;
}

2. Friend classes and friend functions

Friend function

In C++, the private members of a class can only be accessed in this class, and the protected members of a class can only be accessed in this class or a subclass, but the friend functions of the class can access the class’s Private members and protected members.

A friend function of a class is defined outside the class, but has access to all private and protected members of the class. Although the prototype of a friend function appears in the class definition, a friend function is not a member function.

definition:
Functions modified with friend are called friend functions

class ClassName
{
public:
friend void func();
};
void func()
{
}
using namespace std;
class Student {
public:
int v1 = 100;
private:
string name="dld";
protected:
int v3 = 300;
public:
void func1() {
cout << v1 << endl;
cout << v2 << endl;
cout << v3 << endl;
}
friend void printName(Student stu);
};
void printName(Student stu)
{
cout << stu.name << endl;
}
int main() {
Student s1;
printName(s1);
return 0;
}

Friend class

In C++, a class can be declared as a friend class. If a class is a friend class of another class, the friend class can access all private members of the class.

definition:
A class modified with friend is called a friend class.

class ClassName
{
public:
friend class ClassName2;
};
class ClassName2
{
};

Use friend to define a friend class ClassName2. At this time, ClassName2 can access all private members of the class.

class Teacher;
class Student {
private:
string name = "王五";
int age;
public:
void stu_print(Teacher & t);
};
class Teacher {
private:
string name = "Zhang San";
int age;
public:
friend class Student;
};
void Student::stu_print(Teacher & amp; t) {
cout <<this->name << endl;
cout << t.name << endl;
}
int main() {
Student s1;
Teacher t1;
s1.stu_print(t1);
return 0;
}

3, operator overloading

C++ allows multiple definitions of a function and operator in the same scope, which are called function overloading and operator overloading respectively.

An overloaded declaration is a declaration with the same name as a function or method that has been previously declared in the scope, but their parameter list and definition (implementation) are different.

When an overloaded function or operator is called, the compiler determines the most appropriate definition by comparing the parameter types used with the parameter types in the definition. The process of selecting the most appropriate overloaded function or operator is called overload decision-making.

The essence of operator overloading is function overloading, but there are certain rules that need to be followed.

  1. When an operator is overloaded, the order of operations and priority of the operator remain unchanged, and the number of operands remains unchanged.
  2. New operators cannot be created, only existing operators in C++ can be overloaded, and there are 6 operators that cannot be overloaded.
  3. Operator overloading is to appropriately transform the original operators according to the actual needs of the new type. Generally speaking, the function of the overloaded operator should be consistent with the actual meaning of the operator.
Operators that cannot be overloaded Meaning
. Generic relation operator
.* Member pointer operator
:: Scope operator
? : Conditional operator
# Compile preprocessing symbols
sizeof Get the length of the data type

There are two forms of operator overloading, overloading as a member function of the class and overloading as a friend function of the class.

The general syntax form of operator overloading as a member function of a class is:

Function type operator operator (formal parameter list)
{
function body;
}

The general syntax form of operator overloading as a friend function of a class is:

friend function type operator operator (formal parameter list)
{
function body;
}

Since there are many types and numbers of operators, some symbols in the following four categories will be explained.

4 major categories:

  1. Overloading of assignment operators
  2. Overloading of arithmetic operators
  3. .Overloading of relational operators
  4. Other more special overloads
//Overloading of assignment operator
class Student {
private:
string name;
int age;
public:
Student() {
name ="zs";
age = 20;
}
Student(string name, int age) {
this->name = name;
this->age = age;
}
void operator=(const Student & t) {
this->name = t.name;
this->age = t.age;
}
void printInfo() {
cout <<this->name << " " <<this->age << endl;
}
};
int main() {
Student s1, s2("王五", 30);
s2.printInfo();
s2 = s1; //Use assignment operator
s2.printInfo();
return 0;
}
//Overloading of arithmetic operators
class complex {
public:
complex() {
}
complex(double r, double i) {
this->r = r;
this->i = i;
}
complex operator + (complex & amp; c) {
complex c2;
c2.r = this->r + c.r;
c2.i = this->i + c.i;
return c2;
}
complex operator-(complex & amp; c) {
complex c2;
c2.r = this->r - c.r;
c2.i = this->i - c.i;
return c2;
}
void print() {
cout <<this->r << " " <<this->i << endl;
}
private:
double r, i;
}
int main() {
complex c1(11, 12), c2(10, 11), c3, c4;
c3 = c1 + c2;
c3.print();
c4 = c1 - c2;
c4.print();
return 0;
} 
//Overloading of relational operators
class Student {
private:
string name;
int age;
public:
Student() {}
Student(string name, int age) {
this->name = name;
this->age = age;
}
bool operator>(Student & t) {
if (this->name > t.name) {
return true;
}
else {
return false;
}
}
};
int main() {
Student s1("aaa"
, 11), s2("bbb"
\t\t\t, twenty two);
bool b = s2 > s1; //bool b = s1 < s2; bool b = s2 > s1;
cout << b << endl;
return 0;
}
//Other special overloads
const int SIZE = 5;
class Safearr {
private:
int arr[SIZE];
public:
Safearr() {
register int i = 0;
for (; i < SIZE; i + + ) {
arr[i] = i;
}
}
int operator[](int i) {
if (i >= SIZE) {
cout << "The subscript exceeds the maximum value" << endl;
return -1;
}
return arr[i];
}
};
int main() {
Safearr arr;
cout << arr[1] << endl;
cout << arr[100] << endl;
return 0;
}