跳转至

默认参数和函数重载

默认参数

两种特殊的参数:

  • 默认参数(参数的默认值)
  • 占位符参数

默认参数

#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;
}

规则

不要把默认参数作为一个判断标识,去决定执行代码。

一般函数重载比较多。

默认参数应用:

很长时间后 要修改,参数改了原来的就不能用了,使用新的参数 新的参数用默认参数。老代码可以用,新代码也可以使用。