[Elementary C++]–Initialization list&static members&friends&inner classes&anonymous objects

================================================ ==========================

Click to go directly to the personal homepage: Xiaobai is not a program Yuan

C++ series column: C++ headache

Code repository: Gitee

================================================ ==========================

Table of Contents

Preface

Let’s talk about the constructor again

initialization list

explicit keyword

anonymous object

static member

friends

friend function

Friend class

inner class

Understand classes and objects again


Foreword

In the previous articles, we conducted a series of discussions on C++ classes and objects, including understanding of classes and objects, and the six default member functions in classes. In the member function, we learned about the constructor, but there are still some problems with the constructor that require us to continue to study in depth. Let’s start today’s study! ! !

Let’s talk about the constructor again

When creating an object, the compiler gives an appropriate initial value to each member variable in the object by calling the constructor.

class Date
{
public:
Date(int year, int month, int day)
{
//Assignment is not initialization
  _year = year;
  _month = month;
  _day = day;
}
private:
int _year;
int _month;
int _day;
};

Although the object already has an initial value after the above constructor is called, it cannot be called a member variable in the object.
Initialization,the statements in the constructor body can only be called initial value assignment,but not initialization. Because initialization can only initialize
It can be assigned once, but the constructor body can be assigned multiple times.

Initialization list

Initialization list: Begins with a colon, followed by a comma-separated list of data members, each “member variable” followed by
an initial value or expression enclosed in parentheses

class Date
{
public:
Date(int year, int month, int day)
    //Definition, initialization
  : _year(year)
  , _month(month)
  , _day(day)
{}
private:
//Declaration of members
int _year;
int _month;
int _day;
};

Note

1. Each member variable can only appear once in the initialization list (initialization can only be initialized once)
2. The class contains the following members, which must be placed in the initialization list for initialization:

  • Reference member variables
  • const member variable
  • Custom type member variables (when there is no constructor in the class)
class A
{
public:
A(int t)
:_t(t)
{

}
private:
int _t;
};
class Date
{
public:
Date(int year, int month, int day, int i, int & refn)
//Initialization list
:_year(year)
, _month(month)
, _i(i)
, _n(refn)
,_a(0)
{
_day = day;
}
private:
int _year;
int _month;
int _day;
const int _i;
int & _n;
A_a;
};
int main()
{
int n = 30;
int t = 10;
Date d1(2023, 11, 1, 9, n);
return 0;
}

3. Try to use an initialization list for initialization, because no matter whether you use an initialization list or not, for custom type member variables,
It must be initialized using the initialization list first.

4. The order in which member variables are declared in a class is the order in which they are initialized in the initialization list, and the order in which they are placed in the initialization list.
The order does not matter

Take a look at the following question

class A
{
public:
  A(int a)
   :_a1(a)
   ,_a2(_a1)
 {}
 
  void Print() {
    cout<<_a1<<" "<<_a2<<endl;
 }
private:
  int _a2;
  int _a1;
};
int main() {
  A aa(1);
  aa.Print();
}

The answer is 1 random value

According to the above points, first initialize _a2 with _a1, _a1 is a random value, so _a2 is a random value; then use a to initialize _a1, so _a1 is the value of a, which is 1.

explicit keyword

The constructor can not only construct and initialize objects, but also have default values for a single parameter or for all parameters except the first parameter, which has no default value.
The constructor also has the function of type conversion.

explicit keyword
class A
{
public:
A(int a)
:_a(a)
{

}
private:
int _a;
};
int main()
{
A aa(2023);
// Contains implicit type conversion, implicitly converting 2 into a temporary A-like constant, leaving 2 unchanged
aa = 2;
//Removing const will cause the compiler to report an error
    const A & _aa=2;
return 0;
}

Adding the explicit keyword will prevent this implicit type conversion

class A
{
public:
explicit A(int a)
:_a(a)
{

}
private:
int _a;
};
int main()
{
A aa(2023);
aa = 2;
const A & _aa = 2;
return 0;
}

Anonymous object

Features: No need to give a name, the life cycle only has this line

class A
{
public:
void Print()
{
}
~A()
{
cout << "~A() call" << endl;
}
private:
int _a=1;
};

int main()
{
A().Print();
return 0;
}

static member

Class members declared as static are called static members of the class, and member variables modified with static are called static member variables; use
A member function modified by static is called a static member function. Static member variables must be initialized outside the class.

Interview question: Implement a class and calculate how many objects of the class are created in the program and how many objects of the class are left through debugging;

It is definitely not possible to define two variables in a class. If a new class is not created, the members of the class will be re-created.

The first one: Use global variables to solve separately in the construction, copy construction and destructor;

Second: Use static members to implement

We obviously use the second one to achieve this.

class A
{
public:
A()
{
n + + ;
m + + ;
}
A(const A & t)
{
n + + ;
m + + ;
}
~A()
{
--m;
}
//No this pointer
    //After static modification, you can use the domain scope qualifier to directly access the functions in the class
static void Print()
{
cout << n << " " << m << endl;
}
private:
static int n;
static int m;
};
//Initialization outside the class
int A::m = 0;
int A::n = 0;

int main()
{
A aa;
A aaa;
A::Print();
    //Create object access
aa.Print();
A();
    //direct interview
A::Print();
return 0;
}

Note:

1. Static members are shared by all class objects and do not belong to a specific object. They are stored in the static area.
2. Static member variables must be defined outside the class. The static keyword is not added when defining. It is just declared in the class.
3. Class static members can be accessed using class name::static member or object.static member
4. Static member functions do not have a hidden this pointer and cannot access any non-static members.
5. Static members are also members of the class and are restricted by public, protected, and private access qualifiers.

Friendly Yuan

Friends provide a way to break through encapsulation and sometimes provide convenience. However, friends will increase coupling and destroy encapsulation, so
You Yuan should not be used too much.

Friends are divided into: Friend functions and friend classes

Friend function

class A
{
public:
A(int x, int y) :_x(x) {}
//Define the function in the class and add the keyword friend before it
friend int sum(const A & amp; a, const A & amp; b);
private:
int _x;
};
//implemented outside the class
int sum(const A & amp; a, const A & amp; b)
{
//Access private data in the class
int sum = a._x + b._x;
return sum;
}

Friend functions can directly access private members of a class. They are ordinary functions defined outside the class and do not belong to any class, but they need to be
For the internal declaration of a class, the friend keyword needs to be added when declaring.

Description:

  1. Friend functions can access private and protected members of a class, but not member functions of the class
  2. Friend functions cannot be modified with const
  3. Friend functions can be declared anywhere in a class definition and are not restricted by class access qualifiers.
  4. A function can be a friend function of multiple classes
  5. The principle of calling friend functions is the same as that of ordinary functions.

Friend class

All member functions of a friend class can be friend functions of another class and can access non-public members of another class. friends

  • The relationship is one-way and not exchangeable.

For example, in the above Time class and Date class, if you declare the Date class as its friend class in the Time class, you can directly access the private member variables of the Time class in the Date class, but you want to access the private member variables of the Date class in the Time class. No.

  • Friend relationships cannot be transferred

If C is a friend of B and B is a friend of A, it cannot mean that C is a friend of A.

  • Friend relationships cannot be inherited. I will give you a detailed introduction to the inheritance position.
class Time
{
 friend class Date; // Declare the date class as a friend class of the time class, then directly access the Time class in the date class
Private member variables in
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 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;
};

inner class

Concept: If a class is defined inside another class, this internal class is called an internal class. An inner class is an independent class,
It does not belong to the outer class, and it cannot access the members of the inner class through the object of the outer class. Outer classes have no advantage over inner classes
access rights.

Note: The inner class is the friend class of the outer class. See the definition of friend class. The inner class can be accessed through the object parameters of the outer class.
Ask all members in the outer class. But the outer class is not a friend of the inner class.

Features:

1. Inner classes can be defined as public, protected, or private in external classes.
2. Note that the inner class can directly access the static members in the outer class without the object/class name of the outer class.
3. sizeof (external class) = external class, has nothing to do with internal classes.

class A
{
public:
class B
{
//Equivalent to writing friend class A;
public:
void set(A&t)
{
            //Access private data of class A
t._a = 1;
}
private:
int _b;
};
private:
int _a;
};

int main()
{
return 0;
}

Understand classes and objects again

Physical computers in real life do not recognize it. Computers only recognize data in binary format. If you want the computer to recognize the current
To describe the entities in real life, users must describe the entities through some object-oriented language, and then create programs by writing programs.
The computer can only recognize the object after it is created. For example, if you want the computer to recognize the washing machine, you need to:

1. Users must first abstract the reality of the washing machine entity – that is, understand the washing machine at the level of human thinking. What are the functions of the washing machine?
What attributes and functions does it have? It is a process of abstract cognition of the washing machine.
2. After 1, people already have a clear understanding of the washing machine in their minds, but the computer is not clear yet at this time.
Chu, if you want the computer to recognize the washing machine in your imagination, you need to use some object-oriented language (such as: C++,
Java, Python, etc.) describe the washing machine using classes and input them into the computer.
3. After 2, there is a washing machine class in the computer, but the washing machine class only controls laundry from the perspective of the computer.
Machine objects are described. Through the washing machine class, specific washing machine objects can be instantiated. At this time, the computer can
What is a washing machine?
4. Users can use the washing machine object in the computer to simulate the actual washing machine entity.
In the class and object stage, everyone must realize that a class describes a certain type of entity (object) and describes the characteristics of the object.
After the description of these attributes and methods is completed, a new custom type is formed, and this custom type can be instantiated.
specific object.

The major module of classes and objects in the C++ language has been explained in four articles. I hope you will gain something after reading it! ! ! Summarize something of your own. I also hope that everyone will leave a message to point out the content in my article. At the same time, I would like to thank all readers for their continuous support. Your support is the motivation for my updates! ! !

Next article preview – C++ memory management