首页 > 编程语言 >【C++入门】(七)高级函数

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

时间:2022-10-21 10:33:26浏览次数:43  
标签:const 入门 int 函数 C++ 复制 Rectangle 构造函数

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()

标签:const,入门,int,函数,C++,复制,Rectangle,构造函数
From: https://www.cnblogs.com/ZWJ-zwj/p/16812632.html

相关文章

  • C++中的四种强制类型转换
    ①static_cast(expression)<type-id>该运算符把expression转换为type_id类型,但没有运行时类型检查来保证转换的安全性,最常用的是基本数据类型之间的转换 ②const_cast......
  • C++面试问题
    如何实现一个不能被继承的类?将其构造函数设置成私有类型 若仍要访问?设置友元类 实现一个可以被继承的类,但不能在外部函数中创建对象的类型?构造函数设置为受保护......
  • fork函数
    复制进程forkpid_tfork(void)函数返回类型pid_t实质是int类型fork函数会生成一个新的进程,调用fork函数的进程称为父进程,新生成的进程称为子进程,在父进程中返回子......
  • Microsoft_Visual_C++_6-0简体中文版
    软件截图​安全认证官方版评价等级⭐️⭐️⭐️⭐️⭐️发布时间2011-10-1719:47:56更新时间2013-07-0219:47:562022-10-2023:24:10软件版本V6.0应用平台Win2003/Wi......
  • 四大函数式接口
    四大函数式接口Fuction函数型接口,有一个输入参数,有一个输出参数函数型接口:输入一个参数,输出输入的参数//Function函数型接口publicclassDemo01{publics......
  • AJAX入门
    AJAX入门概念:AJAX:异步的JavaScript和XMLAJAX的作用:与服务器进行数据交换:通过AJAX可以给服务器发送请求,并获取服务器响应数据使用了AJAX和服务器进行通信,就可以使用HTM......
  • C++Primer笔记
    数据类型类型转换当赋给无符号类型一个超出它表示范围的值时,结果是初始值对无符号类型所能表示数值的总数取模之后的余数,例如:8bit的unsignedchar可以表示0至255这256个......
  • JSP入门
    JSP入门JSP(全称JavaServerPages)是由SunMicrosystems公司倡导和许多公司参与共同创建的一种使软件开发者可以响应客户端请求,而动态生成HTML、XML或其他格式文档的We......
  • Element快速入门
    Element快速入门概念:Element,一套为开发者、设计师和产品经理准备的基于Vue2.0的组件库,提供了配套设计资源,帮助你的网站快速成型。由饿了么公司前端团队开源。搭建Elem......
  • Go 语言入门很简单:什么是 Golang
    Golang是一种相对较新的编程语言,很快就流行起来。StackOverflow对开发人员进行了民意调查,发现Golang是学习Go编程语言的第三大热门。为了更好地理解为什么Go如此......