C++ classes and objects (static static, friends, internal classes, anonymous objects, explicit) knowledge points + complete mind map + practical map + in-depth details, easy to understand, recommended collection


introduction

        There are three paces of time: the future is long overdue, the present flies like an arrow, and the past stands still forever. This chapter is a concluding chapter on classes and objects. I believe that through the study of these three classes and objects, you should have a clearer understanding of C++ classes and objects.

Not much to say, fasten your seat belt, let's start the car (recommended to watch on computer) .


Attachment: red, the part is the key part; the blue color is the part that needs to be memorized (not rote memorization, knock more); black bold or other colors are the secondary key points; black is the description need


mind Mapping:

 

If you want XMind mind map, you can private message


Table of contents

1. Talk about the constructor again

1.1 Initialization list

1.2:explicit   

2.static

3. Tomomoto

3.2 Friend class

4. Inner classes

5. Anonymous objects


1. Talk about the constructor again

Knowledge points:

We have learned the constructor before, which is used to initialize our members. like:

	Date(int year = 1970, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}

And because in some special cases, the constructor cannot complete some activities, so you can't just use the constructor

So C++ proposes a new concept:

1.1 Initialization list

Knowledge points:

Such as: references, const variables (they all need to be initialized when they are defined , otherwise they cannot be used normally), and custom types ( when there is no default constructor ), they cannot be completed directly through the constructor

 

When an object is defined, its member variables are defined in the initialization list

grammar: 

Basically similar to the constructor , inserting an initialization list in the middle

Date(...)

        : member variable (initial value/variable)

        , Member variables(.....)

        ....

        ,Member variables(.....)

{

        ......

}

And for member variables, the patch in c++11 can give members default values, in fact, this default value is given to the initialization list

 Examples are as follows:

class B {
public:
	/*B()
	{
		_a = 1;
	}*/

	B(int a)
		:_a(a)
	{
		_a = a;
	}
private:
	int _a;
};

class A
{
public:
	A(int& a, int i)
		//而对于成员的初始化是在初始化列表处完成的
		:_a(a)
		, _i(1)
		,bb(10)//此时因为没有默认构造,所以我们只能去调用构造函数,所以需要我们使用初始化列表来进行传参
		,a()//内置类型
	{
	}
private:
	//对于引用和常变量来说他们必须在定义的时候进行初始化,否则就无法使用
	int& _a;
	const int _i;
	//而对于自定义结构来说,也是通过初始化列表来进行初始化的
	B bb;

	//内置类型的缺省值,其实就是给初始化列表的
	int a = 1;
};

int main()
{
	int n = 0;
	A(n,10);
	return 0;
}

detail:

  1. For the initialization list, when you don't write it , the operating system will generate one by default, and it will definitely go through the initialization list
  2. For constructors, the initialization list is of course very strong and can solve most of the definition problems during initialization, but there is a problem if it cannot be completely solved.
  3. The same is true for custom structures, he will automatically call his own constructor through the initialization list , but if it is a built-in type, if it does not give a default value/assign a value in the constructor, it will not automatically initialize
  4. Member variables are initialized in the order of declaration regardless of the order of the initialization list
  5. For 4, we recommend that the order of declarations be consistent with the order of definitions

practise:

Through the initialization list, the custom types without default construction can be initialized (at this time, there are some non-default construction constructors).


1.2:explicit   

For the following code, there is an implicit type conversion

A a = 3;

const A& a = 3;

And under the compiler, the construction + construction will be optimized into only one construction in the case of multiple constructions in one line

It won't work if it's separated

If we don't want it to be able to perform implicit type conversion, we can fully add explicit to the constructor

It will be marked red after use


2.static

Knowledge points:

Concept: Class members declared as static are called static members of the class , member variables modified with static are called static member variables; member functions modified with static are called static member functions. Static member variables must be initialized outside the class , here he is not a member variable of each class object, but a variable shared by each object

Syntax: Add static before variable/function

Initialization needs to be done outside the class, as follows:

class A
{
public:
	A(int a)//并且不能在构造中初始化
	{
	}
private:
	int _a;
	static int _b;//声明
};
int A::_b = 0;//初始化

int main()
{
	return 0;
}

cannot be defined inside a class

detail:

In order to prevent us from changing _b at will, we generally put _b in private.

At this point, you can only get the _b inside by creating an acquisition function/creating a friend function in the class

For the acquisition function, we are generally used to writing it as static . When writing the function as static, at this time, this function does not have a this pointer , so it can only be used through the static member of the general class. Class name:: static member or Object. Static members to access
.

	static int GetB()//一般我们会把这个定义成静态的函数,此时是没有this指针的,指定类域和访问限定符就能进行访问该函数
	{
		return _b;
	}

//访问:
	//cout << a.GetB() << endl;
    cout << A::GetB() << endl;

Note that because there is no this pointer in static functions, member variables/member functions cannot be called, but static functions can be called in member functions. If you must use member functions, you need to pass them in, and you need to be in The parameter part receives

Class static members can be used Class
name:: static members or object. Static members to access Static members are also members of the class, subject to public, protected, private access qualifiers
 

practise:

Design a class that can only create objects on the stack outside the class

Design a class that can only create objects on the heap outside the class

class A {
public:
	static A GetStack()
	{
		A a;
		return a;//返回创建的对象
	}
	static A* GetHeap()
	{
		return new A;//new一个空间给A
	}

private:
	A()
	{}

private:
	int _a = 0;
	int _b = 1;
};

int main()
{
	//此时没有别的办法就只能用静态函数
	//因为构造函数也属于私有的,所以我们不能直接定义一个对象
	A::GetStack();
	A::GetHeap();
	return 0;
}

3. Tomomoto

Knowledge points:

Friends provide a way to break out of encapsulation, and sometimes convenience. However, friends will increase the degree of coupling (association) and destroy the encapsulation, so friends should not be used more often.
Friends are divided into: friend function and friend class

detail:

3.1 Friend function

We have already used operator <<, operator >> in the front , which is used to allow functions to use member variables in a class

Syntax: friend function declaration

  1. A friend function can access the private members of the 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, and the friend keyword needs to be added when declaring.
  2. Friend function cannot be decorated with const (because it has no this pointer)
  3. Friend functions can be declared anywhere in the class definition, not restricted by class access qualifiers
  4. A function can be a friend function of multiple classes

3.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
( same as friend functions, when we define another friend class in a class Object, at this time, you can use the member variables in the declared class in another class )

Specific writing: friend class class name


Practice using:

class B {
friend class A;


private:
	int _b = 10;
};

class A {
public:

	A()
	{}

	void Print()
	{	
		//此时创建一个B类的对象就能去访问其类内的私有
		cout <<  _i._b << endl;
	}

private:
	int _a = 0;
	B _i;
};

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


4. Inner classes

Knowledge points:

A class defined inside another class is called an inner class

detail:

  1. The inner class is a friend class of the outer class, so the member variables of the outer class can be used in the inner class, but the member variables of the inner class cannot be used in the outer class, so we can directly write the member variables of the inner class in the outer , so that they can be used together.
  2. Internal classes are also restricted by public, protected, and private access qualifiers , and when written as private, they cannot be used directly outside the class

Practice using:

There are many details that have been annotated

class A {
public:

	class B {//此时的B就是A的一个内部类,并且内部类时外部类的友元,可以使用外部类的变量
	public:
		B()
		{}
		void Print(const A& a)//注意也并不是直接就能使用其成员变量,还是需要先实例化一个对象的
		{
			cout << a._a << a._b << endl;
		}
	private:

	};

private:
	int _a = 0;
	int _b = 10;

};

int main()
{
	A a;
	A::B b;//当是public 时就能在外部定义了
	return 0;
}	
class A {
public:

	class B {//此时的B就是A的一个内部类,并且内部类时外部类的友元,可以使用外部类的变量
	public:
		B()
		{
		}
		void Print()
		{
			cout << _a <<_b << endl;//此处对于静态成员来说直接通过A::xxx 就能访问,所以对在A类内的B就能直接使用静态的
		}
	private:

	};

private:
	static int _a;
	static int _b;
};

int main()
{
	A a;
	A::B b;//当是public 时就能在外部定义了
	return 0;
}

5. Anonymous objects

Knowledge points:

An anonymous object, in particular, creates an object without an object name , and at this time, the anonymous object is constructed in the creation line, and will be destructed in the next line.

Anonymous object creation method: class name ();

How to use anonymous objects: class name (). The function called;

detail:

  1. Anonymous objects are as constant as temporary variables , so if you want to refer to this object, you need to add const to modify it
    1. 如const A& ra = A();
  2. And for the referenced anonymous object, its life cycle will also be extended to the end of the local function because of being referenced
  3. Attachment: When creating an object, it cannot be written as    Date d();    because the compiler cannot distinguish whether this is a function declaration or the construction of your object, so there is no need to add parentheses for the case of not passing parameters

Specific exercises:

class A
{
public:
	A(int a = 0)
		:_a(a)
	{
		cout << "A(int a)" << endl;
	}
	~A()
	{
		cout << "~A()" << endl;
	}
private:
	int _a;
};
class Solution {
public:
	int Sum_Solution(int n) {
		//...
		return n;
	}
};
int main()
{
	A aa1;//正常的构造
	A();//匿名对象,生命周期在本行

	A aa2(2);//正常的构造
	Solution().Sum_Solution(10);//匿名对象调用其函数,并且此处并不会调用构造函数

	const A& ra = A();//注意匿名对象具有常性,所以需要在引用前面+const
	A aa3(3);//正常的构造
	
	return 0;
}


This chapter is over. To predict what will happen next, let's wait for the next chapter to break it down.

If you have any questions, welcome to discuss!

If you think this article is helpful to you, please like it!

Continuously update a large number of C++ detailed content, pay attention early and don't get lost.

Guess you like

Origin blog.csdn.net/ZYK069/article/details/130795486