什么是c++函数重载 (重载函数和内联函数)

01_inline内联函数

C语言中有宏函数的概念。宏函数的特点是内嵌到调用代码中去,避免了函数调用的开销。但是由于宏函数的处理发生在预处理阶段,缺失了语法检测和有可能带来的语法差错,导致程序运行失败;那么在C++中作者弥补了这个问题,提出了内联函数的概念,内敛函数实现了真正的内嵌。

#include	<iostream>
using namespace	std;	
inline	void	func(int	a)	
{	
				a	=	20;	
				cout	<<	a	<<endl;	
}	
int	main(void)	
{	
				func(10);	
				/*
							//编译器将内联函数的函数体直接展开
				{
								a	=	20;
								cout	<<	a	<<endl;
				}					
				*/					
				return 0;	
}

内联函数的特点:

1)内联函数声明时inline关键字必须和函数定义结合在一起,否则编译器会直接忽略内联请求。

2)C++编译器直接将函数体插入在函数调用的地方 。

3)内联函数没有普通函数调用时的额外开销(压栈,跳转,返回)。

4)内联函数是一种特殊的函数,具有普通函数的特征(参数检查,返回类型 等)。

5) 内联函数由 编译器处理,直接将编译后的函数体插入调用的地方, 宏代码片段 由预处理器处理, 进行简单的文本替换,没有任何编译过程。

6)C++中内联编译的限制: 不能存在任何形式的循环语句 ;不能存在过多的条件判断语句; 函数体不能过于庞大 ;不能对函数进行取址操作;函数内联声明必须在调用语句之前。

7)编译器对于内联函数的限制并不是绝对的,内联函数相对于普通函数的优势只是省去了函数调用时压栈,跳转和返回的开销。因此,当函数体的执行开销远大于压栈,跳转和返回所用的开销时,那么内联将无意义。

02_默认参数和占位参数

通常情况下,函数在调用时,形参从实参那里取得值。对于多次调用同一函数同一实参时,C++给出了更简单的处理办法。给形参以默认值,这样就不用从实参那里取值了。

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>

using namespace std;

void func(int a=100)
{
	cout << "a=" << a << endl;
}

//求立方体体积
int get_volume(int len ,int width,int height=10)
{
	cout << "len=" << len << endl;
	cout << "width=" << width << endl;
	cout << "height=" << height << endl;
	
	return len * width * height;
}

void func2(int x,int=0)//占位参数  参数二无实际意义
{
	cout << "x=" << x << endl;
}
int main()
{
	int value = 10;

	func(value);//函数的返回值是10  如果不传递参数  将会把函数形参的数组返回

	int len = 10;
	int w = 20;
	int h = 30;
	cout << "体积为" << get_volume(len, w) << endl;

	func2(199,10);
	func2(100);
	return 0;
}

03_函数重载

函数重载(Function Overload):用同一个函数名定义不同的函数,当函数名和不同的参数搭配时函数的含义不同。

重载的规则:

1.函数名相同

2.参数个数不同,参数的类型不同,参数顺序不同,均可构成重载

3.返回值类型不同不可以构成重载

void	func(int	a);	//ok
void	func(char	a);	//ok
void	func(char	a,int	b);	//ok
void	func(int	a,	char	b);	//ok
char	func(int	a);	//与第⼀个函数有冲突,重定义
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>

using namespace std;

//函数返回值,函数形参列表(参数个数,参数类型,参数顺序)
//函数重载:函数名形同,但参数列表不同  两个函数互为重载
//函数的返回值不会构成函数重载的条件,即返回值与重载无关
int func(int a, int b)
{
	cout << "func1" << endl;
	return 0;
} 

//函数重载的情况下,不要写默认参数,为避免调用出现歧义
char func(int a, int b,int c=0)
{
	cout << "func2" << endl;
	return 0;
}

int func(int a, char* str)
{
	cout << "func3" << endl;
	return 0;
}

void print1(int a)
{
	cout << "print1" << endl;
	cout << "a=" << a << endl;
}

void print1(double b)
{
	cout << "print2" << endl;
	cout << "b=" << b << endl;
}

void print1(char ch)
{
	cout << "print3" << endl;
	cout << "ch=" << ch << endl;
}

int main()
{
	//func(10,20,30);
	//func(10, "ab");

	print1(10);
	print1(10.000);
	print1(1.1f);
	print1('a');
	//print1("hello");//err
	//如果能够严格匹配电泳完全匹配
	//如果没有完全匹配,调用隐式转换
	//如果都匹配不到,调用失败
	return 0;
}

04_函数重载和函数指针

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>


using namespace std;

int func(int a, int b)
{
	cout << "func(int,int)" << endl;
}

int func(int a, int b, int c)
{
	cout << "func(int,int,int)" << endl;
	return 0;
}

//1.定义一种函数类型
typedef int(MY_FUNC)(int, int);

//2.定义一个指向一种函数类型的指针类型
typedef int(*MY_FUNC_P)(int, int);


int main()
{
	//1.
	MY_FUNC* fp = NULL;
	fp = func;
	fp(10, 20);


	//2.
	MY_FUNC_P fp1 = NULL;
	fp1 = func;
	fp1(10, 20);


	//3.
	int(*fp3)(int, int) = NULL;
	fp3 = func;
	fp3(10, 20);

	func(10, 20);
	func(10, 20, 30);
	fp3 = func;//fp3-> func(int,int)
	
	int(*fp4)(int, int, int) = NULL;
	fp4 = func;//fp4->func(int,int,int)

	fp3(10, 20);//func(int,int)
	fp4(10, 20, 30);

	return 0;
}

05_类和对象

定义一个类,本质上是定义一个数据类型的蓝图。这实际上并没有定义任何数据,但它定义了类的名称意味着什么,也就是说,它定义了类的对象包括了什么,以及可以在这个对象上执行哪些操作。

c++重载函数用处,c++函数重载有什么意义

类的对象的公共数据成员可以使用直接成员访问运算符 . 来访问

c++重载函数用处,c++函数重载有什么意义

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>

using namespace std;

struct Hero
{
	char name[64];
	int sex;
};

void printHero(struct Hero& h)
{
	cout << "Hero" << endl;
	cout << "name=" << h.name << endl;
	cout << "sex=" << h.sex << endl;
}

class AdvHero
{
public:				//访问控制权限
	char name[64];
	int sex;

	void printHero()
	{
		cout << "advHero" << endl;
		cout << "name=" << name << endl;
		cout << "sex=" << sex << endl;
	}
};

class Animal
{
	//{} 以内叫类的内部,以外叫类的外部
public:
	//在public下面定义的成员变量和函数,在类的内部与外部均可访问
	char kind[64];
	char color[64];
	void printAnimal()
	{
		cout << "kind=" << kind << endl;
		cout << "color=" << color << endl;
	}
	void write()
	{
		cout << kind << "开始写字" << endl;
	}
	void run()
	{
		cout << kind << "开始跑步" << endl;
	}
private:
	//在private下面定义的成员变量和方法只能在类的内部访问
};
int main()
{
	Hero h;
	strcpy(h.name, "AA");
	h.sex = 1;
	printHero(h);

	AdvHero advH;
	strcpy(advH.name, "AAA");
	advH.sex = 1;
	advH.printHero();

	cout << "---------" << endl;
	Animal dog;
	strcpy(dog.kind, "dog");
	strcpy(dog.color, "yellow");

	Animal sheep;
	strcpy(sheep.kind, "sheep");
	strcpy(sheep.color, "white");

	dog.write();
	sheep.run();
	return 0;
}

c++重载函数用处,c++函数重载有什么意义

打印结果

06_类的封装

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>

using namespace std;

struct Date
{
	int year;
	int month;
	int day;
};

void init_data(struct Date& d)
{
	cout << "year,month,day" << endl;
	cin >> d.year;
	cin >> d.month;
	cin >> d.day; 
}

//打印data的接口
void print_date(struct Date& d)
{
	cout << d.year << "年" << d.month << "月" << d.day << "日" << endl;
}

bool is_leap_year(struct Date&d)
{
	if (((d.year%4==0)&&(d.year%100!=0))||(d.year%400!=0))
	{
		return true;
	}
	return false;
}

class MyDate
{
public:
	void init_data()
	{
		cout << "year,month,day" << endl;
		cin >> year;
		cin >> month;
		cin >> day;
	}
	//打印data接口
	void print_date()
	{
		cout << year << "年" << month << "月" << day << "日" << endl;
	}
	bool is_leap_year()
	{
		if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 != 0))
		{
			return true;
		}
		return false;
	}

	int get_year()
	{
		return year;
	}

	void set_year(int new_year)
	{
		year = new_year;
	}

protected://保护控制权限。在类的继承中跟private有区别,但单个类中与private相同

private:
	int year;
	int month;
	int day;
};

//一个类的内部,默认的访问控制权限是private
class Hero
{
private:
	int year;
};

//结构体默认访问控制权限是public
struct Hero2
{
	int year;
};

int main()
{
#if 0
	Date d1;
	init_data(d1);
	print_date(d1);
	if (is_leap_year(d1)==true)
	{
		cout << "是闰年" << endl;
	}
	else
	{
		cout << "不是闰年" << endl;
	}

#endif
	MyDate my_date;
	my_date.init_data();
	my_date.print_date();
	if (my_date.is_leap_year()==true)
	{
		cout << "是闰年" << endl;
	}
	else
	{
		cout << "不是闰年" << endl;
	}
	cout << my_date.get_year() << endl;
	my_date.set_year(2000);
	cout << my_date.get_year << endl;

	Hero h;
	//h.year = 100; err 不可访问

	Hero2 h2;
	h2.year = 100;
	return 0;
}

07_面向对象和面向过程

1.面向对象是相对面向过程而言的,面向对象包含了面向过程的思想。

  • 2.面向过程就是分析出解决问题所需要的步骤,关注的是解决问题需要那些步骤。3.面向对象是把构成问题事务分解成各个对象,关注的是解决问题需要那些对象。
  • 示例:做红烧肉

    • 面向过程:
      • 买五花肉
      • 洗净、切块、准备作料等备用
      • 下锅、上色、翻炒等
      • 出锅
    • 面向对象:
      • 准备五花肉
      • 将五花肉下锅
      • 五花肉出锅

    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    
    using namespace std;
    class Dog
    {
    public:
    	void eat(char* food)
    	{
    		cout << name << "吃" << food << endl;
    	}
    	char name[64];
    };
    //面向过程
    void eat(class Dog& dog,char*food)
    {
    	cout << dog.name << "吃" << food << endl;
    }
    
    int main()
    {
    	Dog dog;
    	strcpy(dog.name, "狗");
    	eat(dog, "xiang");//面向过程
    
    	dog.eat("xiang");//面向对象
    	return 0;
    }
    

    08_求圆的周长和面积

    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    
    
    using namespace std;
    
    //圆的周长 
    double getCircleGirth(double r)
    {
    	return 2 * 3.14 * r;
    }
    //圆的面积
    double getCircleArea(double r)
    {
    	return 3.14 * r * r;
    }
    
    
    //面向对象实现以上功能
    class Circle
    {
    public:
    	void setR(double r)
    	{
    		m_r = r;
    	}
    	double get_R()
    	{
    		return m_r;
    	}
    	double get_Girth()
    	{
    		return 2 * 3.14 * m_r;
    	}
    	double get_Area()
    	{
    		return 3.14 * m_r * m_r;
    	}
    
    private:
    	double m_r;//圆的私有成员半径
    };
    
    
    class Circle2
    {
    public:
    	void set_R(double r)
    	{
    		 m_r = r;
    	}
    	double get_R()
    	{
    		return m_r;
    	}
    	double get_girth()
    	{
    		m_girth == m_r * 2 * 3.14;
    		return m_girth;
    	}
    	double get_area()
    	{
    		m_area = m_r * m_r * 3.14;
    		return m_area;
    	}
    private:
    	double m_r;
    	double m_girth ;//周长
    	double m_area ;//面积
    };
    
    
    int main()
    {
    	double r = 10;//圆半径
    
    	double g = 0;
    	double a = 0;
    
    	g = getCircleGirth(r);
    	a = getCircleArea(r);
    	cout << "圆的半径是" << r << endl;
    	cout << "圆的周长是" << g << endl;
    	cout << "圆的面积是" << a << endl;
    
    	cout << "--------------" << endl;
    
    	Circle c;
    	c.setR(20);
    	c.get_Area();
    	c.get_Girth();
    	cout << "圆的半径是" << c.get_R() << endl;
    	cout << "圆的周长是" << c.get_Girth() << endl;
    	cout << "圆的面积是" << c.get_Area() << endl;
    
    	cout << "----------------" << endl;
    
    	Circle2 c2;
    	c2.set_R(30);
    	c2.get_girth();
    	c2.get_area();
    	cout << "圆的半径是" << c2.get_R() << endl;
    	cout << "圆的周长是" << c2.get_girth() << endl;
    	cout << "圆的面积是" << c2.get_area() << endl;
    
    	return 0;
    }
    

    09_求两个立方体是否全等

    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    
    
    using namespace std;
    
    
    //立方体类
    class Cube
    {
    public:
    	void setABC(int a, int b, int c)
    	{
    		m_a = a;
    		m_b = b;
    		m_c = c;
    	}
    
    	int getArea()//面积
    	{
    		return (m_a * m_b) * 2 + (m_a * m_c) * 2 + (m_b * m_c) * 2;
    	}
    
    	int getVolume()//体积
    	{
    		return m_a * m_b * m_c;
    	}
    
    	int getA()
    	{
    		return m_a;
    	}
    	int getB()
    	{
    		return m_b;
    	}
    	int getC()
    	{
    		return m_c;
    	}
    
    	//同类之间数据均可访问
    	bool judgeCube( Cube& another)
    	{
    		if (m_a == another.m_a &&//同类
    			m_b == another.getB() &&
    			m_c == another.getC())
    		{
    			return true;
    		}
    		else
    		{
    			return false;
    		}
    	}
    private:
    	int m_a;//长
    	int m_b;//宽
    	int m_c;//高
    };
    
    //全局函数
    bool judgeCube(Cube& c1,Cube& c2)
    {
    	if (c1.getA()==c2.getA()&&
    		c1.getB()==c2.getB()&&
    		c1.getC()==c2.getC())
    	{
    		return true;
    	}
    	else
    	{
    		return false;
    	}
    }
    
    int main()
    {
    	Cube c1;
    	c1.setABC(10, 20, 30);
    
    	Cube c2;
    	c2.setABC(10, 20, 30);
    
    	cout << "c1体积为" << c1.getVolume() << endl;
    	cout << "c1面积为" << c1.getArea() << endl;
    
    	if (judgeCube(c1,c2)==true)
    	{
    		cout << "两个立方体全等" << endl;
    	}
    	else
    	{
    		cout << "两个立方体不等" << endl;
    	}
    	cout << "----------" << endl;
    	if (c1.judgeCube(c2)==true)
    	{
    		cout << "两个立方体全等" << endl;
    	}
    	else
    	{
    		cout << "两个立方体不等" << endl;
    	}
    	return 0;
    }
    

    c++重载函数用处,c++函数重载有什么意义

    打印结果

    10_求点与圆的位置关系

    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    
    
    using namespace std;
    
    //点类
    class Point
    {
    public:
    	void setXY(int x, int y)
    	{
    		m_x = x;
    		m_y = y;
    	}
    	int getX()
    	{
    		return m_x;
    	}
    	int getY()
    	{
    		return m_y;
    	}
    
    private:
    	int m_x;
    	int m_y;
    };
    
    
    //圆类
    class Circle
    {
    public:
    	void setXY(int x,int y)//圆心
    	{
    		x0 = x;
    		y0 = y;
    	}
    	void setR(int r)
    	{
    		m_r = r;
    	}
    	//提供一个判断点是否在圆内
    	//true 在内部
    	//false 在外部
    	bool judgePoint(Point& p)
    	{
    		int dd;
    		dd = (p.getX() - x0) * (p.getX() - x0) + (p.getY() - y0) * (p.getY() - y0);
    		if (dd>m_r*m_r)
    		{
    			return false;
    		}
    		else
    		{
    			return true;
    		}
    	}
    private:
    	int x0;
    	int y0;
    	int m_r;
    };
    
    int main()
    {
    	Circle c;
    	c.setXY(2, 2);
    	c.setR(4);
    
    	Point p;
    	p.setXY(8, 8);
    	
    	if (c.judgePoint(p)==true)
    	{
    		cout << "点在圆内部" << endl;
    	}
    	else
    	{
    		cout << "点在圆外部" << endl;
    	}
    	return 0;
    }