默认参数和函数重载¶
默认参数¶
两种特殊的参数:
- 默认参数(参数的默认值)
- 占位符参数
默认参数¶
#include <iostream>
using namespace std;
const int ArSize = 80;
//函数声明
char* left(const char* str, int n = 1);
void test()
{
char sample[ArSize];
cout << "Enter a string: \n";
cin.get(sample, ArSize);//输入值
char* ps = left(sample, 4);
cout << ps << endl;
delete[] ps;
ps = left(sample);//使用默认参数
cout << ps << endl;
delete[] ps;
}
//函数实现
char* left(const char* str, int n)
{
if (n < 0) {
n = 0;
}
char *p = new char[n+1];
int i;
for(i=0; i<n && str[i]; i++) {
p[i] = str[i];
}
while (i <= n) {
p[i++] = '\0';
}
return p;
}
函数里面分配了内存 所以上面的调用之后 需要delete删除释放。
默认值只允许在声明里,不允许在定义里。
默认参数后面的参数都要是默认参数。
占位符参数¶
C++函数声明和函数实现 参数的名字可以不一样
函数声明 参数的名字也可以不写,只写类型。写参数的名字是为了人看了,程序员可以看懂参数代表的是什么意思。
函数的定义(实现)里面也可以不写(实现里面没有使用时)。这就叫占位符参数。
适用:
之前使用的参数 后来通过不断的重构修改,不需要了,为了兼容老的调用代码,可能很多地方都调用这个函数方法,所以写成空的。
在函数声明里所有的参数名都可以省略不写,包括默认值的参数名。
但最好写上,并且和定义写一样的名称。
函数重载¶
-
函数重载 多个函数同名
-
多个函数同名,在C语言中不允许同名,C语言没有函数重载。C++可以。
- 名字改编 通过范围和参数进行重载 (编译之后在内部就不是那个简单的名称了)
编译之后 其实名字是不一样的 C++有这个功能。所以使用同一个名称。
注¶
不同返回值的不行!返回值没有用。 只能参数类型 参数个数。
1、普通函数¶
C++多个函数使用相同的名称¶
使用相同的名称,但是参数类型不一样。C++ 会根据参数类型去调用不同的函数。
下面两个函数名一样,但是编译之后在C++内部是不一样的。
void add(int a, int b)
{
int result;
result = a + b;
cout << a << "+" << b << "=" << result << endl;
}
void add(float a, float b)
{
float result;
result = a + b;
cout << a << "+" << b << "=" << result << endl;
}
void test()
{
add(10, 20);
add(1.1f, 2.2f);
}
C语言不允许两个函数同名¶
要给不同的函数写不同的名称。
void add_int(int a, int b)
{
int result;
result = a + b;
printf("%d + %d = %d", a, b, result);
}
void add_float(float a, float b)
{
float result;
result = a + b;
printf("%f + %f = %f", a, b, result);
}
void test()
{
add_int(10, 20);
add_float(1.1f, 2.2f);
}
2、成员函数¶
类的成员函数 构造函数也可以重载。
函数名参数名都一样,但是是在不同的class里,也是可以的。
class Demo1
{
char m_name[16];
public:
//成员函数
void foo(string newName)
{
cout << "Demo1, foo(string newName)" << endl;
}
void foo(int age)
{
cout << "Demo1, foo(int age)" << endl;
}
};
class Demo2
{
char m_name[16];
public:
//成员函数
void foo(string newName)
{
cout << "Demo2, foo(string newName)" << endl;
}
void foo(int age)
{
cout << "Demo2, foo(int age)" << endl;
}
};
//
void test()
{
Demo1 a;
Demo2 b;
a.foo("aaa");
b.foo("bbb");
a.foo(100);
b.foo(200);
}
参数类型不一样 参数个数不一样 都可以重载。 两个类 范围也不一样。
3、构造函数¶
构造函数名称必须和类名是相同的,参数个数不一样 参数类型不一样 都可以。
参数个数不一样就可以。
多个构造函数,设计灵活,
析构函数没有重载,只有一个。
默认参数or函数重载¶
- 容易使用
- 方便重用
- 接口清晰
指针可以动态的分配大小
保存¶
保存到自定义的MEM类中
头文件:¶
#ifndef MEM_hpp
#define MEM_hpp
#include <stdio.h>
typedef unsigned char byte;
class Mem
{
byte* mem;
int size;
void ensureMinSize(int minSize);
public:
Mem();
Mem(int sz);
~Mem();
int msize();
byte* pointer();
byte* pointer(int minSize);
};
#endif /* MEM_hpp */
源文件:¶
#include <string>
//析构函数
Mem::~Mem()
{
delete[] mem;
}
Mem::Mem()
{
mem = 0;
size = 0;
}
Mem::Mem(int sz)
{
mem = 0;
size = 0;
ensureMinSize(sz);
}
void Mem::ensureMinSize(int minSize)
{
if (size < minSize) {
byte* newmem = new byte[minSize];
memset(newmem + size, 0, minSize - size);
memcpy(newmem, mem, size);
delete[] mem;
mem = newmem;
size = minSize;
}
}
int Mem::msize()
{
return size;
}
byte* Mem::pointer()
{
return mem;
}
byte* Mem::pointer(int minSize)
{
ensureMinSize(minSize);
return mem;
}
规则¶
不要把默认参数作为一个判断标识,去决定执行代码。¶
一般函数重载比较多。
默认参数应用:
很长时间后 要修改,参数改了原来的就不能用了,使用新的参数 新的参数用默认参数。老代码可以用,新代码也可以使用。