C++知识点汇总

参考文献 https://github.com/huihut/interview

目录

面向对象

面向对象三大特征 —— 封装、继承、多态
面向对象图

封装

把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。关键字:public, protected, private。不写默认为 private。

  • public成员:可以被任意实体访问
  • protected成员:只允许被子类及本类的成员函数访问
  • private:只允许被本类的成员函数、友元类或友元函数访问

继承

  • 基类(父类)——> 派生类(子类)

多态

  • 多态,即多种状态(形态)。简单来说,我们可以将多态定义为消息以多种形式显示的能力。
  • 多态是以封装和继承为基础的。
  • C++ 多态分类及实现:
    • 重载多态(Ad-hoc Polymorphism,编译期):函数重载、运算符重载
    • 子类型多态(Subtype Polymorphism,运行期):虚函数
    • 参数多态性(Parametric Polymorphism,编译期):类模板、函数模板
    • 强制多态(Coercion Polymorphism,编译期/运行期):基本类型转换、自定义类型转换

重载、重写、重定义

  • 重载
    • 同一个类中的同名函数会重载;
    • 重载函数的函数名相同,参数不同,不能用返回值判断是否是函数重载;
    • 在不同类中的同名函数不是重载。
void func()
    {
        std::cout << "调用了基类的func()" << std::endl;
    }

void func(int a)
{
    std::cout << "调用了基类的func(int)" << std::endl;
}
  • 重写
    • 重写发生在派生类和基类之间;
    • 若派生类和基类有函数原型相同的成员函数,并用virtual关键字声明(基类成员函数用virtual关键字声明即可,而不管派生类成员函数是否用virtual关键字声明),则此成员函数为重写;
    • 若派生类和基类有函数原型相同的成员函数,但没有用virtual关键字声明,则为重定义
    • 重写的派生类成员函数会覆盖与原型相同的基类成员函数。
  • 重定义
    • 重定义发生在派生类和基类之间;
    • 若派生类和基类有函数原型相同的成员函数,但没有用virtual关键字声明,则派生类成员函数为重定义
    • 若派生类和基类有函数名相同但参数不同的成员函数,则派生类成员函数为重定义;
    • 重定义的派生类成员函数会隐藏相应的基类成员函数。

引用和指针的区别

  1. 指针有自己的一块空间,而引用只是一个别名;
  2. 使用sizeof看一个指针的大小是4,而引用则是被引用对象的大小;
  3. 指针可以被初始化为NULL,而引用必须被初始化且必须是一个已有对象的引用;
  4. 作为参数传递时,指针需要被解引用才可以对对象进行操作,而直接对引用的修改都会改变引用所指向的对象;
  5. 可以有const指针,但是没有const引用;
  6. 指针在使用中可以指向其它对象,但是引用只能是一个对象的引用,不能 被改变;
  7. 指针和引用使用++运算符的意义不一样;
  8. 如果返回动态内存分配的对象或者内存,必须使用指针,引用可能引起内存泄露。

引用作为返回值时,必须遵守的规则

  1. 不能返回局部变量的引用

静态链接与动态链接的区别

new和malloc区别

  • 属性:new和delete是C++关键字,需要编译器支持;malloc和free是库函数,需要头文件支持。
  • 参数: 使用new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计算。而malloc则需要显式地指出所需内存的尺寸。
  • 返回类型: new操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换,故new是符合类型安全性的操作符。而malloc内存分配成功则是返回void * ,需要通过强制类型转换将void*指针转换成我们需要的类型。
  • 自定义类型:new会先调用operator new函数,申请足够的内存(通常底层使用malloc实现)。然后调用类型的构造函数,初始化成员变量,最后返回自定义类型指针。delete先调用析构函数,然后调用operator delete函数释放内存(通常底层使用free实现)。malloc/free是库函数,只能动态的申请和释放内存,无法强制要求其做自定义类型对象构造和析构工作。
  • 重载:C++允许重载new/delete操作符,malloc不允许重载。
  • 内存区域:new做两件事:分配内存和调用类的构造函数,delete是:调用类的析构函数和释放内存。而malloc和free只是分配和释放内存。
  • 分配失败:new内存分配失败时,会抛出bac_alloc异常。malloc分配内存失败时返回NULL。
  • 内存泄漏:内存泄漏对于new和malloc都能检测出来,而new可以指明是哪个文件的哪一行,malloc确不可以。

sizeof

定义

  • sizeof 是一个操作符 operator,不是一个函数,其作用是返回一个对象或类型所占的内存字节数

结构体的sizeof

  • 结构体的sizeof()涉及到字节对齐问题,字节对齐的细节和编译器的实现有关,但一般而言,满足3个准则:
    • 结构体变量的首地址能够被最宽基本类型成员的大小所整除
    • 结构体的每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要,编译器会在成员之间填充字节(internal adding)
    • 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要,编译器会在最末一个成员上加上填充字节(trailing padding)
  • 注意:空结构体(不含数据成员)的 sizeof 值为 1
struct S1  
{  
    char a;  
    int b;  
};  
sizeof(S1); //值为 8,字节对齐,在char之后会填充 3 个字节。  
 
//-----------------------------------------------------------------------------------------
 
struct S2  
{  
    int b;  
    char a;  
};  
sizeof(S2); //值为 8,字节对齐,在char之后会填充 3 个字节。  
//-----------------------------------------------------------------------------------------

struct S3  
{  
};  
sizeof(S3); // 值为 1,空结构体也占内存
//-----------------------------------------------------------------------------------------

struct S4
{
    char a;
    int b;
    float c;
    double d;
};
sizeof(S4); //值为 24,在 a 后面补 3 个字节,在 c 和 d 之间补 4 个字节

struct S4_1
{
    double a;
    char b;
    int c;
    float d;
};
sizeof(S4_1);// 值为24, 在 b 后面补3个字节,为了使整体大小能够被最宽的double 8整除,需要在最后面加4个字节。

struct S4_2
{
    int a;
    double b;
    float c;
};
sizeof(S4_2);// 值为 24, 为了使double 的相对于首地址的偏移能够整除 8,在 a 后面补 4 个字节,为了使整体大小能够被最宽的double 8整除,需要在最后面加 4 个字节。

struct S4_3
{
    double d;
    int b;
    float c;
};
sizeof(S4_3); //值为 16,满足条件,不需要填补。
//-----------------------------------------------------------------------------------------

struct S5
{
    char a;
    S4_3 b;
    int c;
};
sizeof(S5); // 值为 32, 要满足结构体 S4_3的首地址可以被其最宽成员 double 8整除,在 a 后应该填充 7 个字节
           //然后为了满足总的成员大小能够被最宽成员 double 8 整除,在 int 后需要填充 4 个字节 

联合体的sizeof

  • 结构体在内存组织上是顺序式的,联合体是重叠式的,各成员共享一段内存,所以整个联合体的sizeof就是每个成员sizeof的最大值
union u  
{  
    int a;  
    float b;  
    double c;  
    char d;  
};  
  
sizeof(u); // 值为 8

指针的sizeof

  • 指针是用来记录另外一个对象的地址,所以指针的内存大小就是计算机内部地址总线的宽度
  • 在32位计算机中,一个指针的sizeof返回值必定是4
  • 指针变量的sizeof值与指针所指的对象没有任何关系
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值