C++ 4

发布于:2025-02-10 ⋅ 阅读:(42) ⋅ 点赞:(0)

堆和栈的区别

堆 (Heap) 和栈 (Stack) 是程序运行时两种不同的内存分配区域
● 内存分配:
○ 栈
■ 是由编译器自动管理的,用于存储局部变量和函数调用的上下文信息。
■ 栈上的对象在定义它们的块或函数调用结束后自动销毁。
■ 栈的内存分配和释放速度很快,因为栈的内存管理是连续的,不需要搜索空闲内存。
○ 堆
■ 由程序员手动管理的,用于存储动态分配的对象。
■ 堆上的对象需要程序员手动释放,否则可能导致内存泄漏。
■ 堆的内存分配和释放速度通常比栈慢,因为可能需要搜索合适的内存块,并且涉及内存碎片整理。
● 大小限制:
○ 栈的大小通常有限制,远小于堆的大小,且在不同系统和编译器中可能不同。
○ 堆的大小通常很大,受限于系统可用内存。
● 使用场景:
○ 栈主要用于存储函数参数、局部变量等。
○ 堆用于存储生存期不受限于单个函数调用的对象,如使用 new 或 malloc 分配的对象。

C++面向对象三大特性

面向对象编程是C++的核心特性之一。OOP是一种编程范式,通过它,程序可以以对象的形式组织数据和功能,并通过对象之间的交互来实现任务。面向对象编程具有封装、继承和多态三个主要特性:

  1. 封装:将客观事物封装成为抽象的类, 类把自己数据和方法进行隐藏,仅对外公开接口来和对象进行交互,防止外界干扰或不确定性访问。
  2. 继承:指一个类(称为子类或派生类)可以从另一个类(称为父类或基类)中继承属性和行为的能力。通过继承,子类可以重用父类的代码,并且可以在不修改父类的情况下添加新的功能或修改已有的功能。继承使得代码具有层次性和可扩展性,能够建立起类之间的层次关系。
  3. 多态:多态是指同一个操作作用于不同的对象时,可以有不同的解释和行为。多态性允许以统一的方式处理不同类型的对象,从而提高了代码的可扩展性和可维护性。在C++中,多态性通常通过虚函数(virtual functions)来实现。通过基类中定义虚函数,并在派生类中重新定义该函数,可以实现运行时的动态绑定。

简述一下 C++的重载和重写,以及它们的区别和实现方式

  1. 重载和重写是两种不同的概念,它们都用于实现多态性,但方式和使用场景有所不同。
  2. 重载:在同一个类或命名空间中,声明多个同名函数, 但是参数列表不同。编译器根据参数的类型、数量或顺序来区分不同的函数。
  3. 重写:重写发生在继承体系中,在子类中,声明一个与父类中虚函数具有相同名称、相同参数列表和相同返回类型的函数,并在子类函数前加上 override 关键字。
  4. 区别:
    ● 作用域:重载发生在同一个作用域内,而重写发生在继承体系中。
    ● 参数列表:对于重载的函数,参数列表必须不同;对于重写的函数,参数列表必须与被重写的函数完全相同。
    ● 返回类型:重载函数的返回类型可以不同,但重写函数的返回类型必须与被重写的函数相同(或与之兼容,C++中称为协变返回类型)。
    ● 虚函数:重写通常与虚函数一起使用,以实现运行时多态性;而重载是编译时多态性,由编译器在编译期间确定调用哪个函数。
    ● 关键字:重写函数可以使用 override 关键字,明确指出该函数是对父类虚函数的重写。

C++怎么实现多态

  1. C++ 的多态分为编译时多态(也被称为静态多态)和运行时多态(也被称为动态动态)
  2. 编译时多态
    ● 函数重载(Function Overloading):允许在同一作用域内声明多个同名函数,只要它们的参数列表不同。
    ● 运算符重载(Operator Overloading): 允许为自定义类型定义或修改运算符的行为。
    ● 模板(Templates): 允许创建泛型类和函数,它们可以在多种数据类型上使用。
    编译时多态在编译期间就确定了具体的函数或类型,由编译器根据函数的签名或模板实例化来选择正确的函数或实例。
  3. 运行时多态: 运行时多态主要通过虚函数和抽象类实现,父类中定义声明虚函数,子类实现对虚函数的重写。由虚函数表和虚函数指针在运行时确定调用哪个函数。
    ● 虚函数(Virtual Functions): 虚函数在基类定义,派生类可以重写这些虚函数。
    ● 抽象类(Abstract Classes): 包含至少一个纯虚函数的类,不能被实例化,但可以作为其他类的基类。
  4. 运行时多态实现原理:
    ● 运行时多态涉及到虚函数表(vtable)和虚函数指针(vptr)。当类包含虚函数时,编译器会自动为该类创建一个虚函数表,表中包含类中所有虚函数的地址。
    ● 子类的虚函数表继承了父类的虚函数表,但会使用自己重写的虚函数将虚函数表中对应的虚函数进行覆盖。
    ● 当通过基类指针或引用调用虚函数时,程序会根据对象的实际类型在运行时查找正确的函数地址并调用相应的函数,实现多态。