Q1·
将引用作为函数参数有哪些特点?
别名:当一个引用被用作函数的参数时,它实际上成为了传递给函数的参数的别名。这意味着任何对引用所指向的对象所做的修改都会影响到原始对象。
传值 vs 传引用:与传值(pass-by-value)不同,传引用(pass-by-reference)不会创建新的副本,而是直接操作原来的变量。这可以避免复制大对象时带来的性能开销。
提高效率:对于较大的数据结构,如自定义类类型或标准库容器(例如 std::vector),使用引用可以显著提高函数调用的效率,因为不需要复制这些对象。
必须初始化:引用必须在定义时被初始化,并且一旦初始化后就不能重新绑定到另一个对象上。
常量引用:可以通过使用常量引用(const reference)来防止函数内部修改传递的参数。这对于只读操作特别有用,可以保证函数不改变其输入。
Q2·
简要介绍自己常用的集成开发环境或者软件开发调试工具。
linux下 编辑工具 vim 命令行模式 底行模式 插入模式
gedit
编译工具 gcc
调试工具 gdb 打印调试
Q3·
new一个对象存放在哪个区?
在C++中,当你使用 new 操作符分配内存时,你实际上是在堆(heap)上分配内存。堆是一个程序运行时动态分配内存的区域,与栈(stack)上的内存不同,堆上的内存由程序员手动管理,即程序员负责分配和释放。
具体来说:
堆(Heap):
堆是在程序运行时动态分配的内存区域。
使用 new 分配的对象存储在这个区域。
堆上的内存分配不会自动回收,需要手动使用 delete 或者 delete[](如果是数组的话)来释放内存。
堆上的内存分配可能会失败,如果分配失败,new 操作会抛出 std::bad_alloc 异常(除非设置了 nothrow 标志)。
栈是用来存放函数的局部变量、函数参数等的区域。
栈上的内存是由编译器自动管理的,当函数退出或者变量的作用域结束时,这些内存会被自动释放。
栈上的内存分配速度快,但是空间有限。
静态区(Static Area):
静态区用于存放全局变量和静态局部变量。
这些变量在整个程序的生命周期内都存在。
常量区(Constant Area):
常量区用来存放字符串常量等常量信息。
这些数据不可修改。
说出来堆区即可
Q4·
在函数内static修饰的变量存放在哪里?
静态区
在C++中,如果在一个函数内部声明了一个带有 static 修饰符的变量,这种变量被称为 静态局部变量(static local variable)。这类变量的行为和存储位置有以下特点:
存储位置:
静态局部变量存储在程序的 静态存储区(static storage area)中。这个区域通常也称为 全局数据区 或 静态数据区,它与全局变量和静态全局变量共享同一个存储区域。
这意味着静态局部变量并不会像普通局部变量那样存储在栈上,也不会像动态分配的对象那样存储在堆上。
生命周期:
静态局部变量在其定义的源文件的作用域内有效,并且在整个程序的执行过程中一直存在。
它们在程序启动时被初始化,并且在程序结束时才被销毁。
初始化:
静态局部变量只会被初始化一次,即使函数多次被调用,初始化也只会在第一次调用时发生。
如果没有显式初始化,静态局部变量会被自动初始化为其类型的默认值(例如,对于内置类型,通常是零值)。
可见性:
尽管静态局部变量存储在静态存储区,它们的作用域仍然是局部的,仅限于声明它的函数内部。
这意味着每次进入函数时都可以访问该静态局部变量的状态,而在函数外部无法访问
Q5·
static修饰的成员变量有什么特点?
在C++中,static 修饰的成员变量(也称为静态成员变量)有一些独特的特点。以下是静态成员变量的主要特点:
单一实例:
静态成员变量在整个类的所有对象中只有一个实例。无论创建了多少个类的对象,静态成员变量只有一个拷贝存在于内存中。
这意味着所有类的对象共享同一个静态成员变量的值。
存储位置:
静态成员变量存储在全局数据区(静态存储区),而不是在堆栈或堆上分配。
因此,静态成员变量的生命周期贯穿整个程序的执行过程,从程序开始到程序结束。
初始化:
静态成员变量可以在类体外进行初始化,通常是在类声明之后,但在任何使用之前。
如果未显式初始化,则根据类型进行默认初始化(例如,内置类型将被初始化为零值)。
访问控制:
静态成员变量可以具有与非静态成员变量相同的访问控制符(public, protected, private)。
即使静态成员变量是私有的,也可以通过类的公共静态成员函数(静态方法)来访问。
访问方式:
静态成员变量可以通过类名直接访问,而不需要创建类的实例。
例如,假设有一个类 MyClass,其中有一个静态成员变量 staticVar,可以通过 MyClass::staticVar 访问。
不依赖于对象:
静态成员变量独立于类的任何特定实例,因此它们不需要通过对象指针或引用访问。
这使得静态成员变量非常适合存储类级别的状态信息或常量。
静态成员函数访问:
类的静态成员函数只能访问类的静态成员变量和其他静态成员函数,不能访问非静态成员变量或非静态成员函数(因为静态成员函数在没有对象的情况下也能调用)。
主要需要体现出:属于类所有对象共享,类内声明,类外定义,需要通过公有的成员函数通过类名直接访问。
Q6·
c++的智能指针使用过吗,都有哪几种,有什么区别?
C++中的智能指针是一类自动管理资源(通常是动态分配的内存)的对象。它们通过在对象生命周期结束时自动释放资源来帮助防止内存泄漏。在C++11及更高版本中,标准库提供了几种智能指针类型,每种都有其特定的用途和行为。
以下是C++中主要的智能指针类型及其区别:
1. `std::unique_ptr`:
- 为独占所有权设计,表示一个对象的唯一控制权。
- 当`std::unique_ptr`被销毁或重新绑定时,它所拥有的资源会被释放。
- 不支持拷贝构造和赋值操作,这意味着资源的所有权不能被共享。
- 支持移动语义,可以将资源的所有权从一个`std::unique_ptr`转移到另一个。
- 适用于大多数场景下的资源管理。
2. `std::shared_ptr`:
- 表示对对象的共享所有权,允许多个`std::shared_ptr`实例同时指向同一个对象。
- 使用引用计数机制来跟踪指向同一对象的`std::shared_ptr`的数量。
- 当引用计数变为零时,对象以及分配给它的资源将被释放。
- 可以通过拷贝构造和赋值操作来创建多个`std::shared_ptr`实例。
- 适用于需要共享资源或者不确定对象所有权的情况。
3. `std::weak_ptr`:
- 与`std::shared_ptr`关联,但不会增加`std::shared_ptr`的引用计数。
- 用于打破循环引用的问题,这是`std::shared_ptr`可能引起的一个问题。
- 当关联的`std::shared_ptr`不再存在时,`std::weak_ptr`会变成无效。
- 可以从`std::weak_ptr`锁定一个`std::shared_ptr`,如果对象仍然存活的话。
这些智能指针的主要区别在于它们如何管理和共享对象的所有权。`std::unique_ptr`适用于单一拥有者的场景,而`std::shared_ptr`则允许共享所有权,并且可以通过`std::weak_ptr`来避免循环引用问题。选择哪种智能指针取决于你希望如何管理对象的生命周期以及是否需要共享对象的所有权。