C + + function overloading

Posted by prawn_86 on Wed, 15 Sep 2021 06:42:12 +0200

Concept:

C++In, under the same scope, the same function name and different parameter lists constitute an overload
 Overloaded functions are usually used to name a group of functions with similar functions, which reduces the number of function names,
It avoids the pollution of namespace and is of great benefit to the readability of the program.

prerequisite:

Under the same scope (not overloaded if different scopes)
As like as two peas, the same function name is the same as the function name.
The parameter list is different:
	1.Different parameter types(Corresponding position)
	2.Different number of parameters
	3.Constant attribute difference refers to pointer or The constant properties of reference types are different
 It is independent of the return value type of the function

In C + +, when calling overloaded functions, the compilation stage determines which function to call according to the number and type of parameters passed during function call
Static Runtime: determines which function to call at compile time
Dynamic runtime: which function to call is determined at run time

For an example, look at function overloading

#include <iostream>
using namespace std;
//
int max(int a,int b){
	cout << "int,int" << endl;
	return a>b?a:b;
}

int max(int a,int b,int c){
	cout << "int,int,int" << endl;
	if(a>=b && a>=c)
		return a;
	if(b>=a && b>=c)
		return b;
	return c;
}
double max(double a,double b){
	cout << "double,double" << endl;
	return a>b?a:b;
}


int main(){
	cout << max(1,2) << endl;
	cout << max(1,2,3) << endl;
	cout << max(3.14,3.33) << endl;
	return 0;	
}

Why do you need function overloading?

Imagine if there is no function overloading mechanism, such as in C, you must do this:
Give this print function a different name, such as print_int,print_string. There are only two cases here. If there are many, you need to take many names for the functions that implement the same function, such as printing long, char *, various types of arrays, etc. This is very unfriendly!
The constructor of the class is the same as the class name, that is:
Constructors have the same name. If there is no function overloading mechanism, it is quite troublesome to instantiate different objects!
Operator overloading is essentially function overloading. It greatly enriches the meaning of existing operators and is convenient to use. For example, + can be used to connect strings!

Rename operation instance

#include <iostream>
using namespace std;

struct Stu{
	int no;
	char name[40];
};


void func(){
	cout << "func()" << endl;	
}
//redefinition
/*
void func(){
	cout << "func()" << endl;	
}
*/
//Ambiguity between old and new definitions
/*
int func(){
	return 1;	
}
*/
void func(int a){
	cout << "func(int)" << endl;	
}
void func(double b){
	cout << "func(double)" << endl;
}
void func(char a){
	cout << "func(char)" << endl;	
}
void func(char a,char b){
	cout << "func(char,char)" << endl;	
}
void func(double a,double b){
	cout << "func(double,double)" << endl;	
}

void func(int a,int b){
	cout << "func(int,int)" << endl;	
}
/*
void func(const int a){
	cout << "func(const int)" << endl;	
}
*/

void func(Stu& s){
	cout << "func(Stu)" << endl;	
}
void func(const Stu& s){
	cout << "func(const Stu)" << endl;	
}

void func(int *pi){
	
}
void func(const int *pi){
	
}
void bar(int& x){
	
}
void bar(const int& x){
	
}
int main(){
	func();
	func('a');//
	func(108);
	func(3.14);
	func('a','b');
	//func(97,'b');// Ambiguity
	func(65.2,77.3);

	return 0;	
}

Here we intercept two compiled assembly codes to see the renaming operation after C + + overloading

_Z4funccc:
.LFB970:
	.cfi_startproc
	pushl	%ebp
	.cfi_def_cfa_offset 8
	.cfi_offset 5, -8
	movl	%esp, %ebp
	.cfi_def_cfa_register 5
	subl	$40, %esp
	movl	8(%ebp), %edx
	movl	12(%ebp), %eax
	movb	%dl, -12(%ebp)
	movb	%al, -16(%ebp)
	movl	$.LC4, 4(%esp)
	movl	$_ZSt4cout, (%esp)
	call	_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
	movl	$_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, 4(%esp)
	movl	%eax, (%esp)
	call	_ZNSolsEPFRSoS_E
	leave
	.cfi_restore 5
	.cfi_def_cfa 4, 4
	ret
	.cfi_endproc
.LFE970:
	.size	_Z4funccc, .-_Z4funccc
	.section	.rodata
.LC5:
	.string	"func(double,double)"
	.text
	.globl	_Z4funcdd
	.type	_Z4funcdd, @function
_Z4funcdd:
.LFB971:
	.cfi_startproc
	pushl	%ebp
	.cfi_def_cfa_offset 8
	.cfi_offset 5, -8
	movl	%esp, %ebp
	.cfi_def_cfa_register 5
	subl	$40, %esp
	movl	8(%ebp), %eax
	movl	%eax, -16(%ebp)
	movl	12(%ebp), %eax
	movl	%eax, -12(%ebp)
	movl	16(%ebp), %eax
	movl	%eax, -24(%ebp)
	movl	20(%ebp), %eax
	movl	%eax, -20(%ebp)
	movl	$.LC5, 4(%esp)
	movl	$_ZSt4cout, (%esp)
	call	_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
	movl	$_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, 4(%esp)
	movl	%eax, (%esp)
	call	_ZNSolsEPFRSoS_E
	leave
	.cfi_restore 5
	.cfi_def_cfa 4, 4
	ret
	.cfi_endproc
.LFE971:
	.size	_Z4funcdd, .-_Z4funcdd
	.section	.rodata
.LC6:
	.string	"func(int,int)"
	.text
	.globl	_Z4funcii
	.type	_Z4funcii, @function

It is found that the two fun become fundd and funccc, so there is no naming conflict.

If you don't want to change the name

extern "C" requires the g + + compiler not to change the name of functions in C + +,
It only works for one function. If you want all of them, you need to include them with {}
To facilitate code generation in C++ language in C language

#include <iostream>
using namespace std;

extern "C"
void func(){//No,
	
}

void bar(){//Changed
	
}


extern "C"{
	void call(){}//No,
	void hello(){}//No,
}

int main(){
	
	return 0;	
}

Function call matching problem during overloading:

1.First, perform exact matching. The number and type of parameters are exactly the same
2.Pointers and references with constant attributes can be overloaded with functions with pointers and references without constant attributes
	If not const Version and const If yes, the matching call is made according to the constant attribute during the call
	If there is only one version of the function, no constant attribute data can be called const edition
	however const Property must not be called const Version function
	Automatic reinforcement const Attribute, but you can't lose it rashly const attribute
#include <iostream>
using namespace std;
/*
void func(int *p){
	cout << "func(int *)" << endl;	
}
*/

void func(const int *p){
	cout << "func(const int *)" << endl;	
}


int main(){
	int *p1;
	const int *p2;

	func(p1);//Auto lift const 
	func(p2);
	return 0;	
}

3.If there is no complete match in the matching process, the parameters will be implicitly converted
 If it is found that two or more functions can be converted equally in the process of implicit conversion, ambiguity will occur
		func(char,char)
		func(int,int)
		func('a',78);//Ambiguity
void f1(char);
void f1(long);

void f2(char*);
void f2(int*);

void k(int i)
{
       f1(i);//Call f1(char)? f1(long)?
       f2(0);//Call f2(char *)? f2(int*)?
}

At this time, the compiler will report an error and throw the error to the user for processing

Topics: C++