C++标准库vector实现原理及扩容复杂度:
std::vector是一个动态数组容器,它内部维护着一块连续内存空间以及当前元素数量。
扩容机制:当向vector添加元素导致容量不足时,vector会自动重新分配更大的内存空间,并将原有数据拷贝到新内存区域,新分配的空间通常是原容量的1.5倍或更大(具体策略与编译器实现有关)。
push_back复杂度分析:如果不需要扩容,时间复杂度为O(1);若需要扩容,则涉及到数据复制,平均情况下是O(n),最坏情况下(每次插入都导致扩容)是O(n),n表示现有元素数量。
C++进程间通信(IPC)的方式: C++本身不直接提供进程间通信API,但可以通过操作系统提供的接口实现IPC,常见的方法包括:
管道(Pipe):用于父进程和子进程之间传递数据。
有名管道(FIFO或命名管道):可用于任意两个进程间的通信。
消息队列(Message Queues):进程间通过发送和接收消息来通信。
共享内存(Shared Memory):不同进程可以直接访问同一块内存区域交换数据。
套接字(Sockets):网络编程中最常用的通信方式,但也适用于本地进程间通信。
信号量(Semaphores)和互斥量(Mutexes):主要用于进程间同步而非数据传输。
构造函数和析构函数是否可以声明为虚函数: 在C++中,构造函数不能被声明为虚函数。因为对象实例化时首先调用的是对应类型的构造函数,而虚函数表是在构造函数初始化对象之后才建立起来的。但是,析构函数可以并且常常被声明为虚函数,尤其是在设计基类和派生类结构时,以确保通过基类指针删除派生类对象时能够正确调用派生类的析构函数。
操作系统执行read系统调用的一般步骤(以POSIX系统为例):
应用程序调用read系统调用,指定文件描述符、缓冲区地址和期望读取的字节数。
CPU从用户态切换到内核态,控制权交由操作系统内核处理。
内核检查文件描述符的有效性,定位相应的文件对象及其对应的设备驱动程序。
根据文件类型的不同,内核可能通过磁盘I/O或者与其他进程/网络进行交互获取数据。
数据准备好后,内核将其复制到应用程序指定的缓冲区中。
如果实际读取的字节数少于请求的字节数,内核更新相关状态(如文件偏移量等)。
完成后,内核触发上下文切换返回到用户态,read调用恢复执行,并返回读取的实际字节数。
智能指针(Smart Pointers)在C++中是用来自动管理堆内存的对象的类模板,它们在析构时会自动释放所指向的对象,从而帮助程序员避免内存泄漏的问题。C++标准库中有三种主要的智能指针类型:
std::unique_ptr:
独占所有权智能指针,确保同一时间内只有一个unique_ptr指向给定对象。
当unique_ptr离开作用域或被重新赋值时,它所指向的对象会被自动删除。
不支持拷贝构造函数和赋值操作符,但可以通过move语义转移所有权。
std::shared_ptr:
共享所有权智能指针,可以有多个shared_ptr共享指向同一个动态分配的对象。
内部使用引用计数机制,当最后一个持有该对象的shared_ptr销毁时,对象也会被自动删除。
支持拷贝、赋值和通过std::weak_ptr进行弱引用。
std::weak_ptr:
弱引用智能指针,不增加所指向对象的引用计数。
用于解决循环引用问题,防止资源无法释放。
使用前需要通过lock()方法尝试获得一个可用的shared_ptr,如果原对象已经被释放,则返回空的shared_ptr。
多态(Polymorphism)**是面向对象编程中的一个重要概念,它允许你用父类类型的指针或引用来处理子类对象,实现不同类之间的接口统一。
在C++中,多态有两种形式:
静态多态(Static Polymorphism 或 Compile-time Polymorphism):
通过函数重载(Overloading)和运算符重载实现,编译器根据上下文决定调用哪个函数。
虚函数表在编译期间就已确定。
动态多态(Dynamic Polymorphism 或 Run-time Polymorphism):
主要通过虚函数(Virtual Functions)和抽象类(Abstract Classes)实现。
在基类中定义虚函数,并在派生类中对其进行覆盖(Override),通过基类指针或引用调用虚函数时,实际执行的是派生类中的实现版本。
动态绑定发生在运行时,具体调用哪个函数取决于指针或引用所指向对象的实际类型。
结合智能指针与多态,可以在处理继承层次结构中动态创建的对象时,利用智能指针进行内存管理的同时,也能够发挥多态的优势,对不同类型的具体对象进行统一处理。