[Basic introduction to C++ (Part 1)]

Cross the stars over the moon to meet your better-self.

 

 

Table of contents

1 namespace

 1.1 Namespace definition

1.2 Namespace usage

1.2.1 Add namespace name and scope qualifier

 1.2.2 Use using to introduce members in the namespace

 1.2.3 Import using using namespace namespace name

2 C++ input && output

3 default parameters

3.1 All default parameters

3.2 Semi-default parameters

4. Function overloading

 4.1 The concept of function overloading

4.2 Name Mangling

 5 summary


1 namespace

In C/C++ , there are a large number of variables, functions, and classes to be learned later. The names of these variables, functions, and classes will all exist in the global scope, which may cause many conflicts. The purpose of using the namespace is to localize the name of the identifier to avoid naming conflicts or name pollution . The appearance of the namespace keyword is aimed at this kind of problem.

 1.1 Namespace definition

To define a namespace, you need to use the namespace keyword , followed by the name of the namespace , and then a pair of {} , which are members of the namespace.

We can give some examples:

#include<stdio.h>
#include<stdlib.h>

int rand = 1;
int main()
{
	
	printf("%d\n", rand);
	return 0;
}

Why does this code report an error?

 After analysis, it is not difficult to find that the rand we defined conflicts with the rand function defined in the official library. The solution is to use namespaces to isolate the variables or functions we define:

namespace grm
{
	int rand = 1;
}

We found that this can be compiled and passed.

Notice:

1 The content in the namespace can define both variables and functions;

2 Namespaces can be nested;

3 Multiple namespaces with the same name are allowed in the same project, and the compiler will finally synthesize them into the same namespace.

Both of the following approaches are reasonable:


// 命名空间可以嵌套
namespace grm
{
	int a;
	int b;
	int Add(int left, int right)
	{
		return left + right;
	}

	namespace N3
	{
		int c;
		int d;
		int Sub(int left, int right)
		{
			return left - right;
		}
	}
}

And finally the compiler will merge the same namespaces in the same project into one namespace. But it is worth noting that once a variable is defined in the namespace, it cannot be modified in the namespace:

 This will cause the compiler to report an error.

A namespace defines a new scope , and everything in the namespace is confined to that namespace. The meaning of this sentence is simply that the namespace we define is an isolated area that will not conflict with variables or functions in the library, so how should we use the namespace?

1.2 Namespace usage

1.2.1 Add namespace name and scope qualifier

What is scope qualifier?

::   (two colons)

namespace grm
{
	int rand = 1;
	int ret = 1001;

	int Add(int x, int y)
	{
		return x + y;
	}
}


int main()
{
	
	printf("%d\n", grm::rand);
	printf("%d\n", grm::ret);
	printf("%d\n", grm::Add(10,20));

	return 0;
}

 1.2.2 Use using to introduce members in the namespace

#include<stdio.h>
//#include<stdlib.h>

namespace grm
{
	int rand = 1;
	int ret = 1001;

	int Add(int x, int y)
	{
		return x + y;
	}
}

using grm::rand;
using grm::Add;
int main()
{
	
	printf("%d\n", rand);
	printf("%d\n", grm::ret);
	printf("%d\n", Add(10,20));

	return 0;
}

At this time, remember to shield the rand in the library, otherwise there will be conflicts.

 1.2.3 Using the using namespace namespace name to import

This method is the simplest, but it is not recommended to be used in projects, otherwise there may be naming conflicts, and ordinary code exercises can be done in this way (because the amount of code is not too large, generally there will be no conflicts)

using namespace grm;
int main()
{
	
	printf("%d\n", rand);
	printf("%d\n", ret);
	printf("%d\n", Add(10,20));

	return 0;
}

2 C++ input && output

#include<iostream>

int main()
{
	int i;
	char c;
	double d;
	std::cin >> i >> c >> d;
	std::cout << i << " " << c << " " << d << std::endl;
	return 0;
}

illustrate:

1. When using cout standard output ( console ) and cin standard input ( keyboard ) , the < iostream > header file and the std standard namespace must be included .
Note: In the early standard library, all functions were implemented in the global domain, declared in the header file with the suffix of . , also in order to use the namespace correctly, it is stipulated that the C++ header file does not contain .h ; the old compiler (vc 6.0) also supports the <iostream.h> format, and the subsequent compiler does not support it, so it is recommended to use <iostream>+std The way.
2. It is more convenient to use C++ to input and output, without adding data format control, such as: integer --%d , character --%c
3 where << represents the stream caret    >> represents the stream extractor .
4 endl means newline.

 But it is very troublesome to always use std:: above. In normal practice, we can directly use it to make it easier.

using namespace std directly imports all functions and variables in the library, but this is not recommended in projects.

#include<iostream>
using namespace std;
int main()
{
	int i;
	char c;
	double d;
	cin >> i >> c >> d;
	cout << i << " " << c << " " << d << endl;
	return 0;
}

We found that using cin && cout does not care about the type of the variable, unlike the C language, you have to remember to use %d characters for shaping, %c and so on. But everything is not absolute. Sometimes it is easier to use scanf && printf than cin && cout. The specific situation is analyzed in detail. Generally speaking, whichever is convenient to use can even be used in combination.


3 default parameters

Do you know what a spare tire is?

 The default parameters are almost as a role as a spare tire

The default parameters are further divided into full default parameters and semi-default parameters.

3.1 All default parameters

#include<iostream>
using namespace std;

int Add(int x = 10, int y = 20, int z = 30)
{
	return x + y + z;
}
int main()
{
	cout << Add(1, 2, 3) << endl;
	cout << Add(1, 2) << endl;
	cout << Add(1) << endl;
	cout << Add( ) << endl;

	return 0;
}

Output result:

 We found that the acceptance of parameters is from left to right.

3.2 Semi-default parameters

void Func(int a, int b = 10, int c = 20)
{
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	cout << "c = " << c << endl << endl;
}

int main()
{
	Func(1);
	Func(1, 2);
	Func(1, 2, 3);
	return 0;
}
Notice:
1. Semi-default parameters must be given sequentially from right to left , and cannot be given alternately
This way is wrong:

 2. Default parameters cannot appear in function declaration and definition at the same time

We redefine a Func.h header file, put the declaration of Func in it, and then compile:

 We only need to put the default parameter in one of them, which is usually defined in the declaration.

 3. The default value must be a constant or a global variable

4. C language does not support (compiler does not support)


4. Function overloading

In natural language, a word can have multiple meanings, and people can judge the true meaning of the word through the context, that is, the word is overloaded. For example: There used to be a joke that people don't need to watch or worry about two state-owned sports events. One is table tennis and the other is men's soccer. The former is " No one can win! " The latter is " No one can win! "

 4.1 Concept of function overloading

Function overloading : It is a special case of functions. C++ allows several functions of the same name with similar functions to be declared in the same scope . The formal parameter lists ( parameter number or type or order ) of these functions with the same name must be different , which is often used to deal with The implementation function is similar to the problem of different data types.
int Add(int left, int right)
{
	return left + right;
}

int Add(int left, char right)
{
	return left + right;
}

int Add(char right, int left)
{
	return left + right;
}

int Add(char right, int left, int mid)
{
	return left + right + mid;
}


int main()
{
	cout << Add(1, 2) << endl;
	cout << Add(1, 'a') << endl;
	cout << Add('a', 1) << endl;
	cout << Add(1, 'a', 2) << endl;

	return 0;
}

 All of the above constitute function overloading:

 But what about this kind?

int Add(int left, int right)
{
	return left + right;
}

char Add(int left, int right)
{
	return left + right;
}
int main()
{
	Add(1, 3);
	return 0;
}

 Obviously, the compiler reported an error at this time. Note: Different return values ​​cannot constitute overloading . Because you don't know which one to call when the function is called.

Can this constitute overloading?

void f()
{
	cout << "f( )" << endl;
}

void f(int x = 0)
{
	cout << "f( x=0 )" << endl;
}

Let's compile the code and find that it can run through, which means that this constitutes overloading , but if you call the function with parameters, it's okay, if you don't take parameters, the compiler doesn't know which function to call, and it will report an error .

4.2 Name Mangling

Why does C++ support function overloading, but C language does not support function overloading?

In C/C++ , for a program to run, it needs to go through the following stages: preprocessing, compiling, assembling, and linking .

For specific details, please refer to my blog program environment and preprocessing

1. Actually, our project is usually composed of multiple header files and multiple source files, and through the compilation and linking of our C language stage learning, we can know that [currently a.cpp calls the Add function defined in b.cpp When], after compiling and before linking, there is no function address of Add in the object file of ao , because Add is defined in b.cpp , so the address of Add is in bo . So what to do?
2. So the link stage is dedicated to dealing with this kind of problem. The linker sees that ao calls Add , but there is no address of Add , it will find the address of Add in the symbol table of bo , and then link them together .
3. When linking, facing the Add function, which name will the linker use to find it? Each compiler here has its own rules for decorating function names.
4. Since the modification rules of VS under Windows are too complicated, and the modification rules of gcc under Linux are simple and easy to understand, we use gcc to demonstrate the modified name below.
5. From the following, we can see that the name of the gcc function remains unchanged after modification. And the modified function of g++ becomes [ _Z+ function length + function name + type initials].
The result after compiling with a C language compiler:
Conclusion: Under linux , after compiling with gcc , the modification of the function name has not changed.
The result after compiling with a C++ compiler:
Conclusion: Under linux , after compiling with g++ , the modification of the function name changes, and the compiler converts the function parameter type information
added to the modified name.
Name modification rules under Windows :

 Comparing Linux , you will find that the C++ compiler under Windows modifies function names very strangely , but the reason is the same.

[Extended learning: C/C++ function calling convention and name modification rules]

C++ function overloading

Everyone here is interested to know about it.
6. Through this, I understand that the C language cannot support overloading, because there is no way to distinguish functions with the same name. C++ is distinguished by function modification rules. As long as the parameters are different, the modified names are different, and overloading is supported.
7. In addition, we also understand why function overloading requires different parameters! It has nothing to do with the return value.
Interview questions:
1. Can the following two functions form function overloading? Is there a problem or what might go wrong?
void TestFunc(int a = 10)
{
 cout<<"void TestFunc(int)"<<endl;
}
void TestFunc(int a)
{
 cout<<"void TestFunc(int)"<<endl;
}

Answer: It is obvious that these two functions cannot constitute function overloading, because the number or type or order of parameters are the same , and it is impossible to identify which function to call after passing the parameters.

2. Why can't C language support function overloading?
Answer: Because the function names of the two overloaded functions are the same during compilation, there will be ambiguities and conflicts in the symbol table, and there will also be conflicts during linking, because they are directly identified and searched by the function name.

 3. How is the bottom layer of function overloading handled in C++ ?

Answer: Because C++ does not directly use the function name to identify and search the function, but uses the function name to modify the rules. As long as the number, type and order of the parameters are different, there will be no ambiguity and conflict in the function of the symbol table. When linking It is also clear when calling two overloaded functions to find the address.


 5 summary

This article introduces the definition and use of namespaces, the use of C++ input and output, default parameters and function overloading, focusing on how function overloading is implemented and why C language does not support function overloading and C++ supports function overloading. The citation will be in the next blog post.

If this article is useful to you, can you support the broadcaster with one click and 3 links?

 

Guess you like

Origin blog.csdn.net/m0_68872612/article/details/128389268
Recommended