0621# C++八股 1.成员初始化列表的概念?以及为什么使用它会快一点?2.重写Override和重载Overload区别

成员初始化列表的概念?以及为什么使用它会快一点?

成员初始化列表的概念

在C++中,成员初始化列表是构造函数的一部分,它用于在构造函数体执行之前初始化类的成员变量。成员初始化列表在构造函数参数列表之后,以冒号 : 开始,并以逗号分隔各个成员的初始化。

成员初始化列表的格式

cpp 复制代码
class MyClass {
private:
    int a;
    int b;

public:
    MyClass(int x, int y) : a(x), b(y) {
        // 构造函数体
    }
};

在上面的示例中,a 和 b 在构造函数体执行之前被初始化为 x 和 y 的值。

为什么使用成员初始化列表会快一点?

  1. 直接初始化 vs. 赋值初始化:

    • 直接初始化:在成员初始化列表中,成员变量直接被初始化。
    • 赋值初始化:如果在构造函数体内进行初始化,首先会调用成员变量的默认构造函数,然后再在构造函数体内赋值。

    成员初始化列表避免了不必要的默认构造和赋值操作,直接在初始化时赋值。因此,这种方式更高效,尤其对于复杂类型(如类对象)和不可默认构造的类型(如引用和常量)。

  2. 常量和引用成员:

    • 常量和引用成员必须通过成员初始化列表进行初始化,因为它们在创建时必须被初始化,不能在构造函数体内赋值。

示例对比

使用成员初始化列表
cpp 复制代码
class MyClass {
private:
    int a;
    int b;

public:
    MyClass(int x, int y) : a(x), b(y) {
        // a 和 b 在构造函数体执行之前已经初始化
    }
};
在构造函数体内赋值
cpp 复制代码
class MyClass {
private:
    int a;
    int b;

public:
    MyClass(int x, int y) {
        a = x;
        b = y;
    }
};

在第二个示例中,a 和 b 在对象创建时先调用默认构造函数,然后在构造函数体内被赋值,这可能会带来额外的开销。

成员初始化列表的使用场景

  1. 必须初始化的成员变量:

    • 常量(const)和引用(&)成员变量。
  2. 提高效率:

    • 直接初始化成员变量,避免多余的默认构造和赋值操作。
  3. 多继承和虚基类:

    • 在多继承或虚基类情况下,基类的构造函数也应在成员初始化列表中显式调用,以确保正确初始化。

总结

  • 成员初始化列表:用于在构造函数体执行之前初始化成员变量,提供更高效的初始化方式。
  • 直接初始化 vs. 赋值初始化:直接初始化避免了多余的默认构造和赋值操作,提高了性能。
  • 使用场景:特别适用于必须初始化的成员变量(如常量和引用),以及需要提高效率的情况。

重写Override和重载Overload区别

重载(Overload)

重载是指在同一个作用域内定义多个同名函数,这些函数具有不同的参数列表(参数的数量或类型不同)。编译器通过函数调用时的参数来决定具体调用哪个重载函数。

关键点
  1. 同一作用域内:重载函数必须在同一个类或同一个命名空间中。
  2. 不同的参数列表:重载函数的参数数量或参数类型必须不同。
  3. 返回类型无关:重载函数的返回类型可以相同也可以不同,但返回类型不能作为区分函数重载的依据。
cpp 复制代码
class Example {
public:
    void func(int a) {
        std::cout << "Function with one int parameter: " << a << std::endl;
    }

    void func(double a) {
        std::cout << "Function with one double parameter: " << a << std::endl;
    }

    void func(int a, double b) {
        std::cout << "Function with one int and one double parameter: " << a << ", " << b << std::endl;
    }
};

int main() {
    Example ex;
    ex.func(10);         // 调用第一个重载函数
    ex.func(3.14);       // 调用第二个重载函数
    ex.func(10, 3.14);   // 调用第三个重载函数
    return 0;
}

重写(Overriding)

重写是指在派生类中重新定义基类中已经存在的虚函数。重写的目的是提供派生类特有的实现。重写只能在类的继承层次中发生,并且需要通过虚函数实现。

关键点
  1. 继承关系:重写函数必须在派生类中定义,且必须与基类中的虚函数同名。
  2. 相同的参数列表:重写函数的参数列表必须与基类中虚函数的参数列表完全相同。
  3. 虚函数 :基类中的函数必须声明为 virtual。
  4. 返回类型:重写函数的返回类型必须与基类中虚函数的返回类型相同,或者是返回类型的协变类型(派生类类型)。
cpp 复制代码
class Base {
public:
    virtual void display() const {
        std::cout << "Display from Base class" << std::endl;
    }
};

class Derived : public Base {
public:
    void display() const override {
        std::cout << "Display from Derived class" << std::endl;
    }
};

void show(const Base& obj) {
    obj.display();
}

int main() {
    Base base;
    Derived derived;

    show(base);    // 调用 Base 类的 display
    show(derived); // 调用 Derived 类的 display

    return 0;
}
相关推荐
DevOpenClub2 小时前
职教高考控制线 API:招生类别枚举、筛选与空分数含义
java·数据库·高考
十二2 小时前
【洛谷题解】P1083 [NOIP 2012 提高组] 借教室(二分答案 + 差分)
数据结构·c++·算法·蓝桥杯
露天赏雪3 小时前
第3篇:Sentinel熔断降级实战:大模型接口抖动时的服务兜底方案
java·开发语言·人工智能·spring boot·spring·servlet·sentinel
天天被压力3 小时前
【A股分钟级高频数据完全手册 #06】北交所分钟级数据接口:京市股票Pro版最新分时
java·人工智能·python
天天被压力3 小时前
【A股分钟级高频数据完全手册 #05】指数历史分钟数据接口:Pro版沪深指数分时回放
java·人工智能·python
captain3763 小时前
▲统一功能——DispatcherServlet源码分析
java·spring·java-ee·log4j·maven
金銀銅鐵3 小时前
JDK 21 中 List.of 的实现细节:从 List12 到 ListN
java·后端·ai编程
D e re k ZH4 小时前
C++ 从零入门(一):基础语法与程序结构
数据结构·c++·算法
yeccheng5 小时前
MySQL 索引超详解:从底层 B+ 树到面试高频考点
java·开发语言·jvm·mysql·面试
这个昵称不容易5 小时前
SpringBoot 读书笔记共享平台部署实战:97 个 Java 文件 / 113 个接口 / 10 张表
java·springboot·毕设