Personal homepage: @Weraphael
? About the author: Currently learning C++ and algorithms
Column: C++ Airway
I hope you will support us a lot, and we will make progress together!
If the article is helpful to you
Welcome to comment Like Favorite Add concern?
Table of Contents
- 1. Friends
-
- 1.1 Friend functions
-
- 1.11 Friend function features
- 1.12 Why Friends are Not Recommended
- 1.2 Friend class
-
- 1.21 Features of friend classes
- Second, the inner class
-
- 2.1 Characteristics of inner classes
- 3. Anonymous objects
-
- 3.1 Characteristics of anonymous objects
1. Friends
Friends provide a way to break encapsulation. Friends are divided into: friend function and friend class.
1.1 Friend function
We used friend functions when implementing the date class. When overloading
operator<<
, it is found that there is no way to overloadoperator<<
into a member function, because the first parameter of a member function is usually athis
pointer. whilecout
's
The output stream object and the implicitthis
pointer are preempting the position of the first parameter. Thethis
pointer defaults to the first parameter, which is the left operand. But in actual use,cout
needs to be the first formal parameter object to be used normally. Therefore,operator<<
can only be overloaded as a global function. But this will lead to no way to access members outside the class, and friends are needed to solve it.operator>>
is the same.
#include <iostream> using namespace std; class Date {<!-- --> public: // friend statement // (The following two functions can use member variables in the class) friend istream & amp; operator>>(istream & amp; cin, Date & amp; x); friend ostream & amp; operator<<(ostream & amp; cout, const Date & amp; x); private: int Year; int Month; int Day; }; istream & amp; operator>>(istream & amp; cin, Date & amp; x) {<!-- --> cin >> x.Year >> x.Month >> x.Day; return cin; } ostream & amp; operator<<(ostream & amp; cout, const Date & amp; x) {<!-- --> cout << x.Year << "Year" << x.Month << "Month" << x.Day << "Day"; return cout; } int main() {<!-- --> Date d1; cin >> d1; cout << d1 << endl; return 0; }
[Result display]
1.11 Friend function features
- Friend functions can access private and protected members of a class, but not member functions of the class
This is because the member function is called through the object of the class, and the object must be present to call the member function. The friend function does not belong to the member function of the class, so it cannot directly access the member function of the class.
- Friend functions cannot be modified with
const
A friend function is defined outside the class and it can access the private members of the class. The
const
keyword means that the member function will not modify the state of the object, but the friend function is not bound to any object, nor is it subject to class access control, soconst The code> modifier has no meaning for friend functions.
- Friend functions can be declared anywhere in the class definition, not restricted by class access qualifiers
- A function can be a friend function of multiple classes
- The principle of calling a friend function is the same as that of a normal function
1.12 Why is friend not recommended
- First of all, friends break the principle of encapsulation: it exposes the implementation details of the class to the outside, increasing the complexity and difficulty of the code.
- The friendship relationship is one-way. If you need to access the private members of multiple classes, you need to make a friend declaration in each class, which will increase the difficulty of code maintenance.
- Finally, friends destroy the inheritance relationship of classes, and subclasses cannot inherit the friendship relationship in the base class, thus limiting the maintainability and scalability of the code.
- Therefore, while friends can be convenient in some cases, in general they are not recommended.
1.2 Friend class
#include <iostream> using namespace std; class time {<!-- --> friend class Date; public: Time(int hour = 0, int minute = 0, int second = 0) : _hour(hour) , _minute(minute) , _second(second) {<!-- -->} private: int _hour; int_minute; int_second; }; class Date {<!-- --> public: Date(int year = 1900, int month = 1, int day = 1) :_year(year) ,_month(month) , _day(day) {<!-- -->} void SetTimeOfDate(int hour, int minute, int second) {<!-- --> // Directly access the private member variables of the time class _t._hour = hour; _t._minute = minute; _t._second = second; } private: int_year; int_month; int_day; Time_t; };
The above code declares the friend class of the Date
class in the Time
class, and then directly accesses the Time class in the Date
class strong>
1.21 Features of friend classes
- The friendship relationship is one-way and not exchangeable.
For example, the above
Time
class andDate
class, declareDate
class as its friend class in theTime
class, then You can directly access the private member variables of theTime
class in theDate
class, but want to access theDate
in theTime
class Private member variables in the class are not allowed
- Friendship cannot be passed
If
C
is a friend ofB
, andB
is a friend ofA
, it cannot explainC
is a friend ofA
.
- Friend relationship cannot be inherited
2. Inner class
If a class is defined inside another class, the inner class is called an inner class.
#include <iostream> using namespace std; class A {<!-- --> public: // B is an inner class of A class B {<!-- --> public: void foo(const A & a) {<!-- --> \t\t\t } }; private: static int k; int h; }; // How to define static member variables int A::k = 1;
2.1 Characteristics of inner classes
- The inner class can be defined in
public
,protected
,private
of the outer class. - The inner class is an independent class, it does not belong to the outer class, note: You cannot access the members of the inner class through the object of the outer class. Outer classes do not have any privileged access to inner classes
- But The inner class is the friend class of the outer class. The inner class can access all members of the outer class through the object parameter of the outer class. (In short, the inner class can access all members of the outer class, but the outer class cannot). And the inner class can directly access the
static
members of the outer class, without the object/class name of the outer class
#include <iostream> using namespace std; class A {<!-- --> public: A(int i = 3) :h(i) {<!-- --> } // B is an inner class of A class B {<!-- --> public: void foo(const A & a) {<!-- --> // Inner classes can directly access static members in outer classes cout << k << endl; // Inner class can access all members of outer class cout << a.h << endl; } }; private: static int k; int h; }; // How to define static member variables int A::k = 1; int main() {<!-- --> A a1; A::B b; //Definition of inner class \t b. foo(a1); return 0; }
[Procedure Results]
sizeof(outer class) = outer class
, has nothing to do with inner class
#include <iostream> using namespace std; class A {<!-- --> public: A(int i = 3) :h(i) {<!-- --> } // B is an inner class of A class B {<!-- --> public: void foo(const A & a) {<!-- --> // Inner classes can directly access static members in outer classes cout << k << endl; // Inner class can access all members of outer class cout << a.h << endl; } }; private: static int k; int h; }; // How to define static member variables int A::k = 1; int main() {<!-- --> cout << sizeof(A) << endl; return 0; }
[Procedure Results]
Note: Member variables modified by
static
do not need to be calculated. Because static member variables belong to the class, each object belonging to the class is shared, and does not belong to a specific object, and is stored in the static area.
3. Anonymous object
Features of Anonymous Objects No Name
#include <iostream> using namespace std; class A {<!-- --> public: \t// Constructor A(int i) :a(i) {<!-- --> cout << "call constructor" << endl; } // destructor ~A() {<!-- --> cout << "call destructor" << endl; } private: int a; }; int main() {<!-- --> A(2); // anonymous object A a(1); // named object \t return 0; }
But The life cycle of an anonymous object is only one line, we can see that it will automatically call the destructor in the next line, and the declaration cycle of the famous function is the local domain of the current function.
3.1 Characteristics of anonymous objects
- Anonymous objects have constant properties
const
refers to an anonymous object, and its life cycle is the same as that of a named object: the local scope of the current function
A(2)
will first call the copy construction, and then print "call construction" on the screen, and then due to type conversion, a temporary variable will be generated in the middle, and the temporary variable also has constant properties. Then the temporary variable is copied and constructed tox
. So, this should call construction twice, why is it only called once? The reason is: For this kind of continuous construction, the compiler will directly optimize and use direct construction to improve efficiency.