0 Basics Introduction to C++ and Objects Part 2

1. Talk about the constructor again

First, let's recall the constructor:

The constructor is a special member function with the same name as the class name, which is automatically called by the compiler when creating a class type object to ensure that each data member has a suitable initial value, and is called only once in the entire life cycle of the object. That is, the constructor is actually to help us assign an initial value to the member variables of the class.

1.1 Constructor assignment

Let's look at an example:

class Date
{
    
    
public:
	Date(int year, int month, int day)
	{
    
    
		_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 the initialization of the member variables in the object.Statements in the body of a constructor can only be called initializing, and cannot be called initialization. becauseInitialization can only be initialized once, and multiple assignments can be made in the constructor body

Let's look at another example:

class T
{
    
    
private:
	int _T1;
	int _T2;
};


Here int _T1; int _T2;is the declaration of the member variable _ T1、 _T2, and here we just declare the two member variables in the class.

Where is the definition?

Here is the quote
Here is the definition of the object as a whole

So when is each member variable of the object defined?

I think the old iron must be thinking like this in his heart at this time:The variable is defined as a whole, aren't its members also defined? Don't the members all belong to this object?

Let's look at this example again:

insert image description here
Here we find that the program cannot run normally. Let's think about it, what are the characteristics of const modified variables?
Yes or noVariables modified by const must be initialized when they are defined

I think at this time everyone must have thought of:

When we explained the constructor before, we said that C++11 allows built-in type member variables to be given default values ​​​​when they are declared in the class .
insert image description here
This program can run

But this was only proposed by C++11, what about before C++11? How to solve such a problem?

So we must also find a definition location for member variables, otherwise member variables like const are not easy to handle.

So where is the member variable definition?

1.2 Initialization list

Faced with the above problems, our ancestors still focused on the constructor.
In the constructor, there is another thing called - initialization list

Initialization list: Starts 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 .

for example:

For the initialization of const int _a in the above class , we can put it in the initialization list for processing:

class T
{
    
    
	public:
	T(int t1, int t2, int a)
	: _T1(t1)
	, _T2(t2)
	, _a(a)
	{
    
    

	}
private:
	int _T1;
	int _T2;
	const int _a = 1;
};


int main()
{
    
    

	T t(1,2,3);
	return 0;
}

Notice:

  1. Each member variable can only appear once in the initialization list (initialization can only be initialized once)

Here is the quote

  1. The following three class member variables must be placed in the initialization list for initialization:

reference member variable

const member variable

custom type member without default constructor

It is not difficult to understand here,Because both reference member variables and const member variables must be initialized when they are defined

For custom type members without a default constructor:

Because the constructor generated by default does not deal with built-in types, it will call its corresponding default constructor for custom types (constructors that do not need to pass parameters are all default constructors), so if the custom type member does not have a default constructor function we need to initialize it ourselves.

  1. Try to use initialization list initialization, because whether you use initialization list or not, member variables will be defined in initialization list.

  2. The order in which member variables are declared in the class is the order in which they are initialized in the initialization list, regardless of their order in the initialization list

1.3explicit keyword

Let's give an example first:

class T
{
    
    
	public:
	T(int t1)
	: _T1(t1)
	{
    
    

	}
private:
	int _T1;
	int _T2;

};

We can create objects this way:

int main()
{
    
    

	T t(1);
	return 0;
}

In addition to this:

int main()
{
    
    

	T t2 = 1;

	return 0;
}

In this place T t2 = 1;, 1 is an integer, how can we directly initialize a class object?
In fact, here is an implicit type conversion. It is the same as the implicit type conversion conversion between built-in types, which will generate a temporary variable

So T t2 = 1;how is it converted here?

A temporary variable will also be generated here. This temporary variable is an object of type T constructed with 1, and then this temporary object is used to copy and construct our t2.

Let's prove it with a small example:

class T
{
    
    
	public:
	T(int t1)
	: _T1(t1)
	{
    
    
		cout << "T(int t)" << endl;
	}
	T(const T& t)
	: _T1(t._T1)
	{
    
    
		cout << "T(const T& t)" << endl;
	}
private:
	int _T1;
};


int main()
{
    
    
    T t2 = 1;
	return 0;
}

Notice:The copy constructor also has an initialization list, because the copy constructor is an overloaded form of the constructor.
So let's run the program now, seeT t2 = 1; Do you use the 1 call constructor to create a temporary variable first, and then call the copy construction to construct t2
insert image description here
The constructor is indeed called here, but the copy constructor is not called

Where is the problem?

In fact, the C++ compiler will optimize the temporary variables generated by the custom type. The compiler uses 1 to construct an object, and then adjusts the copy construction, and the efficiency is affected, so it is optimized into one step, and directly uses 1 to construct the object we want to create,
.
Of course, not all compilers will optimize, but generally newer compilers will optimize here.

What I want to tell you here is:

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

So if we don't want it to support type conversion here, is there any way?

This requires a keyword - explicit
we just prefix the corresponding constructor with explicitthe keyword:
insert image description here
insert image description here

This type of conversion is supported for single-parameter constructors, but what about multi-parameter constructors?

Here C++98 does not support implicit type conversion for multi-parameter constructors. But C++11 has extended this block so that multi-parameter constructors can also perform implicit type conversion
insert image description here

2. static members

2.1 Concept

declared asstatic class membersknown asstatic member of class,usestaticdecorativeMember variables, call itstatic member variable;usestatic modificationmember function of , calledstatic member functionStatic member variables must be initialized outside the class

So what is the use of static members? Let's look at a small topic first:

Implement a class and calculate how many class objects are created in the program.

Guys, think about it, what can you do?

First, a class object must be created, which must be created through a constructor or copy construction.Then we can define a global variable n with an initial value of 0. Then let n++ every time the constructor is called or the object is created by copy construction

But is this approach really good?

Actually it's not very good,First of all, here we define a global variable, first of all, it may cause naming conflicts; second, global variables can be accessed anywhere (C++ pays attention to encapsulation)

I think at this time, the old iron may think of another method:

We put the n variable that counts the number into the class, so that it belongs to the class domain, and if we don't want it to be accessed outside the class, we can modify it to be private.

But is this approach really feasible?

If it is directly placed in the class as a member variable of the class, then it belongs to the object, but we need to count the number of objects created in the program, so that every time we create an object n, it will be defined once, is it not possible? You can't make it belong to every object, you should make it belong to the whole class.

2.1 Static member variables

For the above problem we can solve it like this:

Add a static modifier in front of it to make it a static member variable. Then it no longer belongs to a specific object, but is stored in the static area and shared by all class objects.It is stipulated that the initialization of static member variables (assigning initial values ​​when defining) must be outside the class, the static keyword is not added when defining, and only declarations are made in the class
insert image description here

2.2 Static member functions

Static member functions have a feature: static member functions have no hidden this pointer and cannot access any non-static members.
Because non-static members belong to the object and are accessed through the this pointer, and static member functions do not have this pointer.

2.3 Features

  1. Static members are shared by all class objects, do not belong to a specific object, and are stored in the static area
  2. Static member variables must be defined outside the class. The static keyword is not added when defining. The class is only declared. Static member variables must be initialized outside the class.
  3. Class static members can be accessed with 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 a class, subject to public, protected, private access qualifiers

3. Anonymous objects

Now there is such a class:

class T
{
    
    
	public:
	 T(int t1 = 0)
	: _T1(t1)
	{
    
    
		cout << "T(int t)" << endl;
	}
	~T()
	{
    
    
		cout << "~T()" << endl;
private:
	int _T1;
};

We now want to use this class to create objects. In addition to the methods we learned before, we can actually create objects like this:
insert image description here
Here we use the class T to create an anonymous object.
The characteristic of an anonymous object is that it has no name, but its life cycle is only in the line where it is created.

But beware,Like temporary variables, if we use an anonymous object to initialize a reference, its lifetime will be extended until the reference is destroyed. And const must be added here, because both temporary variables and anonymous objects are constant.

What is the use of anonymous objects?

Now there is a class Solutionwith a non-static member function in it Sum_Solution. We know that if we want to call the non-static member function in the class, we need to call it through the object:
insert image description here

ThatNow that we have an anonymous object, we can call it like this
insert image description here
insert image description here

4. Friend function

Friends provide a way to break out of encapsulation, and sometimes convenience. But friends will increase the degree of coupling and destroy the encapsulation, so friends should not be used more often.

Friends are divided into: friend function and friend class

4.1 Friend functions

In the previous study of classes and objects, we talked about operator overloading:

Now try to overload operator<<, and find that there is no way to overload operator<< into a member function.Because the output stream object of cout and the implicit this pointer are preempting the position of the first parameter. The this 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. So overload operator<< into a global function. But it will cause no way to access members outside the class, and friends are needed to solve it. operator>>The same reason.
insert image description here

A friend function can directly access the private members of a class. It is an ordinary function defined outside the class and does not belong to any class, but it needs to be declared inside the class. The keyword friend needs to be added when declaring

illustrate:

  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 the class, not limited by class access qualifiers
  4. A function can be a friend function of multiple classes
  5. The principle of calling a friend function is the same as that of a normal function

4.2 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 .

  1. The friendship relationship is one-way and not exchangeable.
  2. Friendship cannot be passed

If C is a friend of B and B is a friend of A, it cannot be said that C is a friend of A

  1. The friendship relationship cannot be inherited, and I will give you a detailed introduction in the inheritance position.

5. Inner classes

Concept: If a class is defined inside another class, the inner class is called an inner class.

For example:

class A
{
    
    
private:
	int a;
public:
	class B 
	{
    
    
	private:
		int b;
	};
};

The inner class does not belong to the outer class, it is independent of the corresponding outer class, and is only limited by the domain of the outer class.
For the above class, we want to use the internal class B in A to create objects, which is not possible:
insert image description here

This will work:
insert image description here

Inner classes are inherently friend classes of their corresponding outer classes. See the definition of a friend class, the inner class can access all members of the outer class through the object parameters of the outer class. But the outer class is not a friend of the inner class.

characteristic:

  1. The inner class can be defined in the public, protected, and private of the outer class.
  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(outer class) = outer class, has nothing to do with inner class.

6. Understand classes and objects again

Physical computers in real life do not know, computers only know data in binary format. If you want the computer to recognize entities in real life, users must describe the entities through some object-oriented language, and then write programs to create objects before the computer can recognize them. For example, if you want the computer to recognize the washing machine, you need:

  1. The user first needs to abstract the reality of the washing machine entity—that is, to understand the washing machine at the level of human thought, what attributes the washing machine has, and what functions it has, that is, a process of abstract cognition of the washing machine
  2. After 1, people have a clear understanding of the washing machine in their minds, but the computer is still unclear at this time. To make the computer recognize the washing machine in people's imagination, people need to use some kind of object-oriented language ( For example: C++, Java, Python, etc.) describe the washing machine with classes and input it into the computer
  3. After 2, there is a washing machine class in the computer, but the washing machine class only describes the washing machine object from the perspective of the computer. Through the washing machine class, each specific washing machine object can be instantiated. At this time, the computer can wash the washing machine What is it.
  4. The user can use the washing machine object in the computer to simulate the washing machine entity in reality.

In the class and object stage, everyone must realize that,A class is a description of a certain type of entity (object), which properties and methods the object has. After the description is completed, a new custom type is formed, and then the custom type can be instantiated specific object
insert image description here

Guess you like

Origin blog.csdn.net/weixin_69423932/article/details/132508559