• C-CPP 编程基础


    STL 库描述

    STL 库包括:容器、算法以及融合两者的迭代器。

    容器分为顺序容器和关联容器。顺序容器比如 vector 是一个动态分配存储空间的容器。区别于 C++ 中的 arrayarray 分配的空间是静态的,分配之后不能被改变,而 vector 会自动重分配(扩展)空间。

    内存中堆和栈的区别

    • 栈内存:由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈,都是先进后出。栈使用的是一级缓存,他们通常都是被调用时处于存储空间中,调用完毕立即释放**。
    • 堆内存:一般由程序员分配释放,若程序员不释放,程序结束时可能由 OS 回收。堆是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些。

    堆栈溢出一般是由什么原因导致的?

    没有垃圾回收资源。

    sizeof 的作用

    sizeof 运算符返回一条表达式或一个类型名字所占的字节数,其满足右结合规律。

    C++ 面向对象特点

    数据抽象、继承和动态绑定

    多态的理解

    • 同一函数作用于不同的对象,会对应不同的实现,从而产生不同的执行结果。在运行时,可以通过指向基类的指针或引用,来调用实现派生类中的方法。
    • C++ 的多态性具体体现在运行和编译两个方面:在程序运行时的多态性通过继承和虚函数来体现;在程序编译时多态性体现在函数和运算符的重载上;

    虚函数的理解

    Python 不同,在 C++ 中,基类将类型相关的函数与派生类不做改变直接继承的函数区分对待。对于某些函数,基类希望它的派生类各自定义适合自身的版本,此使基类就会将这些函数声明成虚函数。同时,派生类内部必须在其内部对所有重新定义的虚函数进行声明。(参考 C++ Primer p526 页)

    派生类必须使用类派生列表(class derivation list)明确指出它是从哪个(哪些)基类继承而来。派生的形式是:首先一个冒号,后面紧跟以逗号分隔的基类列表,其中每个基类前面可以有访问说明符。

    class Student: public People{
        string names;
        virtual  double get_gpa (vector scores);
    }
    
    • 1
    • 2
    • 3
    • 4

    动态绑定的理解

    在 C++ 语言中,,当我们使用基类的引用(或指针)调用一个虚函数时,将发生动态绑定,即函数运行的版本由实参决定,运行时自动选择函数的版本。

    C++构造函数初始化时什么时候只能用初始化列表?

    如果类成员是 const、引用。或者属于某种未提供默认构造函数的类类型时,我们必须通过构造函数初始值列表为这些成员提供初始值。(参考 C++ Primer p259)

    C++ 构造函数和析构函数的初始化顺序

    本回答参考C++ 构造函数初始化顺序, C++奇奇怪怪的题目之构造析构顺序

    多个基类的派生类(多继承) 的构造函数初始化按照如下顺序进行:

    1. 先执行虚拟继承的父类的构造函数;
    2. 然后从左到右执行普通继承的父类的构造函数;
    3. 接着按照定义的顺序执行数据成员的初始化;
    4. 最后调用类自身的构造函数;

    析构函数就无脑的将构造函数顺序反转即可。多继承形式下的构造函数和单继承形式基本相同,只是要在派生类的构造函数中调用多个基类的构造函数。

    实例代码如下:

    
    #include 
     
    using namespace std;
     
    class OBJ1
    {
    public:
        OBJ1() { cout << "OBJ1" << endl; }
        ~OBJ1() { cout << "OBJ1 destory" << endl;}
    };
     
    class OBJ2
    {
    public:
        OBJ2() { cout << "OBJ2\n"; }
        ~OBJ2(){cout << "OBJ2 destory" <
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    程序输出结果如下:

    Base2
    Base4
    Base1
    Base3
    OBJ1
    OBJ2
    Derived ok
    construct ok
    Derived destory
    OBJ2 destory
    OBJ1 destory
    Base3 destory
    Base1 destory
    Base4 destory
    Base2 destory

    全局变量和局部变量在内存中是否有区别?如果有,是什么区别?

    全局变量储存在静态数据区,局部变量在堆栈中。

    C++ 中的 new delete 和 C 语言中的 malloc free 有什么区别

    虽然这两者都分别是完成分配内存和释放内存的功能,但是 C++new 分配内存时会调用构造函数,用 delete 释放内存时会调用析构函数。

    new、delete、malloc、free 区别

    • newdeleteC++ 的运算符,mallocfree 是 C++/C 语言的标准框函数,都可用于申请动态内存和释放内存。
    • new 动过调用对象的构造函数来申请动态内存;delete 通过调用对象的析构函数来释放内存。
    • 对于非内部数据类型的对象而言,只用 maloc/free 是无法满足动态对象的要求。我们知道对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。但由于 malloc/free 是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于 malloc/free。因此 new/delete 其实比 malloc/free 更灵活。

    static 关键字作用

    • 声明全局静态变量:在全局变量前加上关键字 static,全局变量就定义成一个全局静态变量,作用域在声明它的文件之外是不可见的,即从定义之处开始到文件结尾
    • 局部静态变量:在局部变量前加上关键字 static,作用域仍然为局部作用域,即当定义它的函数或者语句块结束的时候,作用域结束。
    • 静态函数: 在函数返回类型前加 static,静态函数只在声明他的文件中可见,不能被其他文件使用。
    • 类的静态成员:在类中,静态成员可以实现多个对象之间的数据共享,即静态成员是类的所有对象中共享的成员,而不是某个对象成员。并且使用静态数据成员不会破坏隐藏的原则,保证了数据的安全性。
    • 类的静态函数:把函数成员声明为静态的,就可以把函数与类的任何特定对象独立开来。静态成员函数即使在类对象不存在的情况下也能被调用,静态函数只要使用类名加范围解析运算符 :: 就可以访问(<类名>::<静态成员函数名>(<参数表>))

    类的 static 变量在什么时候初始化?函数的 static 变量在什么时候初始化?

    类的静态成员变量在类实例化之前就已经存在了,并且分配了内存。函数的static 变量在执行此函数时进行初始化。

    C++ 变量作用域

    作用域即是程序的一个区域,在程序中变量的作用域一般有三个地方:

    • 在函数或者一个代码块内部声明的变量,称为局部变量;
    • 在函数参数中定义的变量,称为形参;
    • 在所有函数外部声明的变量,比如在程序文件开头定义的变量,称为全局变量。

    C++ 指针和引用的区别

    • 指针有自己的内存空间,而引用只是一个别名,类似于Python浅拷贝和深拷贝的区别
    • 不存在空引用, 引用必须链接到一块合法的内存地址;
    • 一旦引用被初始化为一个对象,就不能指向另一个对象。指针可以在任何时候指向任何一个对象;
    • 引用必须在创建时被初始化。指针可以在任何时间初始化。
    • 指针可以有多级,但是引用只能是一级(int **p;合法 而 int &&a 是不合法的)。

    C++ 中析构函数的作用

    析构函数与构造函数对应,类的析构函数是类的一种特殊的成员函数,它会在每次删除所创建的对象时执行。析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀,它不会返回任何值,也不能带有任何参数。析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。

    C++ 静态函数和虚函数的区别

    静态函数在编译的时候就已经确定运行时机,虚函数在运行的时候动态绑定。虚函数因为用了虚函数表机制,调用的时候会增加一次内存开销。

    ++i 和 i++ 区别

    ++i 先自增1,再返回,i++,先返回 i,再自增1.

    const 关键字作用

    const类型的对象在程序执行期间不能被修改改变。

    C++如何传递数组给函数

    首先要知道的是,C++ 传数组给一个函数,该数组类型会自动转换为指针,因此实际传递的是地址。

    一维数组作为形参有以下三种方式,多维数组作为形参类似。

    • 形参是一个指针;
    • 形参是已定义大小的数组;
    • 形参是未定义大小的数组。
  • 相关阅读:
    django-rest-framework 基础二 序列化器和路由
    vue3+ts+vite搭建项目
    按键精灵中的字符串常用的场景
    Android高仿网易云音乐-启动界面实现和动态权限处理
    Hadoop大数据开发__HBase分布式集群安装部署
    龙蜥开发者说:首次触电,原来你是这样的龙蜥社区? | 第 8 期
    修改 echarts 默认样式记录
    linux查看所有用户
    java+python+nodejs设备配件采购报修进销存管理系统
    A loam位姿结果缺1帧;rosbag收不到第1帧;kittihelper转的bag
  • 原文地址:https://blog.csdn.net/qq_20986663/article/details/126892318