【C++入门】(十六)高级函数

1. 如何重载成员函数?

  1. 函数重载: 编写多个 名称相同但参数不同 的函数

  2. 成员函数也可以重载

    编译器根据参数数量和类型决定调用哪个构造函数

复制代码
class Rectangle
{
public:
    Rectangle(int a, int b); 
    ~Rectangle() {};
​
    //重载成员函数Func()
    void Func()const;
    void Func(int a,int b)const;
​
private:
    int a = 0; 
    int b = 0;
};
​
Rectangle::Rectangle(int A, int B)
{
    a = A;
    b = B;
}
​
void Rectangle::Func()const
{
    cout << "调用成员函数:void Rectangle::Func()const" ,a =" << a << " b =" << b << endl;
}
​
void Rectangle::Func(int a, int b)const
{
    cout << "调用有参成员函数:void Rectangle::Func(int a, int b)const,a =" << a << " b =" << b << endl;
}
​
int main()
{
    Rectangle test(2, 3);
    cout << "1. 成员函数:Func()" << endl;
    test.Func();
​
    cout << "2. 有参成员函数:Func(int a, int b)" << endl;
    test.Func(5, 6);
​
    return 0;
}
​
//1. 成员函数:Func()
//调用成员函数:void Rectangle::Func()const,a =2 b =3
//2. 有参成员函数:Func(int a, int b)
//调用有参成员函数:void Rectangle::Func(int a, int b)const,a = 5 b = 6
复制代码

 

  1. 使用默认值

    代码功效与上面一样,但可读性没有上面的好,也不易维护

复制代码
class Rectangle
{
public:
    Rectangle(int A, int B); 
    ~Rectangle() {};
​
    //使用默认值
    void Func(int c, int d, bool Value)const;
​
private:
    int a = 0; 
    int b = 0;
};
​
Rectangle::Rectangle(int A, int B)
{
    a = A;
    b = B;
}
​
void Rectangle::Func(int c, int d, bool Value)const
{
    int num1, num2;
    if (Value == true)
    {
        num1 = a;
        num2 = b;
        cout << "调用成员函数:void Rectangle::Func()const,a =" << a << " b =" << b << endl;
    }
    else
    {
        num1 = c;
        num2 = d;
        cout << "调用成员函数:void Rectangle::Func()const,a =" << c << " b =" << d << endl;
    }
}
​
int main()
{
    Rectangle test(2, 3);
    cout << "1. 成员函数:Func()使用默认值" << endl;
    test.Func(0, 0, true);
​
    cout << "2. 成员函数:Func()" << endl;
    test.Func(5, 6, false);
​
    return 0;
}
​
//1. 成员函数:Func()使用默认值
//调用成员函数:void Rectangle::Func()const,a = 2 b = 3
//2. 成员函数:Func()
//调用成员函数:void Rectangle::Func()const,a = 5 b = 6
复制代码

 

  1. 既然可以重载函数,为何还使用默认参数值?

    维护一个函数比维护两个函数容易,且理解带默认参数的函数比研究两个函数的函数体更容易(更新了一个重载函数版本,容易忽略另一个而导致bug)

  2. 重载函数可以有默认参数嘛?

    可以。

    可以有一个或多个重载函数有默认参数,规则与在常规函数中使用默认参数相同

 

2. 如何支持包含动态分配变量的类?

  1. 效率提高空间的一种简单情况:

    const int num1 = 10;
    int num2 = 90 + num1;  //100
    //表达式 90 + num1 的两个组成部分都是常量,编译器将计算这个值,并存储结果100(就像把100赋值给num2)
     
  2. 函数可使用关键字 const 来返回常量值:

    const int num1()
    {
        return 100;
    }
    ​
    int num2 = 90 + num1();  //190
    //虽然这个成员函数 num1() 返回的是一个常量,但这个函数本身不是 const 的,它可能修改全局变量 或调用非 const 成员函数

     

  3. 常量表达式,使用关键字 constexpr

    constexpr int num1()
    {
        return 100;
    }
    ​
    constexpr int num2 = 90 + num1();  //190
    //常量表达式的返回值类型不能为 void,必须返回一个表达式(表达式只能包含字面值、其他常量表达式 或使用constexpr 定义的表达式)

 

3. 如何初始化对象?

  1. 构造函数也可以重载,重载构造函数 是一种强大而灵活的功能

  2. 但不可以重载析构函数,析构函数 不接受任何参数

    Rectangle2::Rectangle2(): a2(5),b2(6)
    {
    }
    ​
    //在冒号后列出要初始化的变量名(在初始化部分设置成员变量,也可以在函数体内设置)

  3. 由于不能给引用和常量赋值,初始化成员变量的效率比给它们赋值要高

  4. 尽可能在初始化部分初始化所有成员变量,有些代码必须放在构造函数的函数体内

 

4. 如何创建复制构造函数?

  1. 除了 默认构造函数默认析构函数,编译器还提供一个 默认复制构造函数 ,每当创建对象的备份时,都将调用复制构造函数

    按值将对象传入或传出函数时,都将创建对象的一个临时备份。如果对象是用户定义的,就将调用相应类的复制构造函数

  2. 所有复制构造函数都接受一个 常量引用 作为参数,指向所属类的对象

    (复制函数不用修改传入的对象,const 常量引用更好)

    Tricycle(const Tricycle &trike)
    ​
    //构造函数 Tricycle 接受一个常量引用,它指向一个现有的 Tricycle 对象
    //这个复制构造函数的目标是 创建 Tricycle 对象的备份
    
    
  3. 复制对象时,默认复制构造函数 复制其所有成员变量

  4. 默认复制构造函数只是将作为参数传入的对象的每个成员变量复制到新对象中,这称为 浅复制(成员复制)

  5. 浅复制 将一个对象的成员变量的值复制到另一个对象中,对于大多数成员变量来说这没问题,但 不适用于指向堆中对象的指针,因为这会导致两个对象中的指针指向相同的内存地址

  6. 解决这种问题的方案是:自己定义复制构造函数(该构造函数接受一个参数(要复制的原始对象));并在复制时正确地分配内存(让指针指向新分配的堆内存)。

    通过创建采用 深复制 的复制构造函数,将把现有值复制到新内存中

    复制代码
    class DeepCopy
    {
    public:
        DeepCopy();  //构造函数
        DeepCopy(const DeepCopy&);  //复制构造函数
        ~DeepCopy();  //析构函数
      
        int get()const { return *p; }
        int set(int newp) { return *p = newp; }
    ​
    private:
        int* p;
    };
    ​
    DeepCopy::DeepCopy()  //构造函数
    {
        cout << "调用构造函数DeepCopy()" << endl;
        p = new int;
        *p = 5;
    }
    ​
    DeepCopy::DeepCopy(const DeepCopy& r)  //复制构造函数
    {
        cout << "调用复制构造函数DeepCopy(const DeepCopy& r)"<< endl;
        p = new int;
        *p = r.get();
    }
    ​
    DeepCopy::~DeepCopy()  //析构函数
    {
        cout << "调用析构函数~DeepCopy()" << endl;
        delete p;
        p = NULL;  //也可以将指针设为 0 置空,效果一样
    }
    ​
    int main()
    {
        cout << "1. 创建DeepCopy类对象HHH " << endl;
        DeepCopy HHH;
    ​
        cout << "2. (通过调用复制构造函数并传递HHH) 创建DeepCopy类对象UUU" << endl;
        DeepCopy UUU(HHH);
    ​
        cout << "HHH.get(): " << HHH.get() << endl;
        cout << "UUU.get(): " << UUU.get() << endl;
      //将旧的 DeepCopy 类对象指向的值复制到新的 DeepCopy 类对象分配的内存中
        
        UUU.set(10);
        cout << "HHH.get(): " << HHH.get() << endl;
        cout << "UUU.get(): " << UUU.get() << endl;
      //修改 UUU 不会动到 HHH,证明它们存储在不同的内存区域
    return 0;
    }
    ​
    //1. 创建DeepCopy类对象HHH
    //调用构造函数DeepCopy()
    //2. (通过调用复制构造函数并传递HHH) 创建DeepCopy类对象UUU
    //调用复制构造函数DeepCopy(const DeepCopy & r)
    //HHH.get() : 5
    //UUU.get() : 5
    //HHH.get() : 5
    //UUU.get() : 10
    //调用析构函数~DeepCopy()
    //调用析构函数~DeepCopy()
    复制代码
posted @   哟吼--小文文公主  阅读(52)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示