[C/CPP笔记]关键字篇

序言:山下旌旗在望,山头鼓角相闻。 敌军围困万千重,我自岿然不动。 早已森严壁垒,更加众志成城。 黄洋界上炮声隆,报道敌军宵遁。《西江月·井冈山》


【看山是山】


【看山不是山】
1. nullptr与NULL有什么区别?

nullptr是C++11引入的类型安全的空指针常量,类型是std::nullptr_t。NULL通常被定义为0或((void*)0),在某些情况下可能引起类型混淆。

2. volatile、virtual和explicit?

volatile、virtual和explicit是三个非常重要的关键字,它们用于不同的目的,影响变量的存储、类的继承和构造函数的使用。

volatile:

作用:volatile关键字用于指示编译器不要对标记的变量进行优化,提示该变量可能会在程序外部被修改,如硬件寄存器或中断服务例程。

用法:volatile通常用于多线程编程、嵌入式系统编程和信号处理,以确保变量的值总是从内存中读取,而不是使用寄存器中的缓存值。

virtual

作用: virtual关键字用于声明虚函数,使得派生类可以覆盖基类中的函数,实现多态。它允许在运行时决定调用哪一个类的成员函数。

用法: 在基类中使用virtual声明虚函数,派生类可以通过覆盖该虚函数实现多态行为。

explicit

作用: explicit关键字用于防止构造函数进行隐式转换或复制初始化。它强制要求使用显式的类型转换,从而避免不必要的或意外的类型转换。

用法: 通常用于单参数构造函数,以防止编译器自动进行类型转换。

3. 多讲一些关于virtual的东西:CPP多态有哪些实现?

多态:允许一个接口以不同方式实现。

(1) 静态多态

原理:编译器在编译时根据函数签名(函数名、参数类型、入参数量)决定具体调用哪个函数。

a.重载(在编译时期就可以通过函数名和参数确定需要调用那个函数);

b.模板

(2) 动态多态

原理:依赖于虚函数表、虚函数指针。当一个类中有虚函数时,编译器为该类创建一个虚函数表,表中储存了该类的虚函数地址。每个对象都有一个虚函数指针(vptr),指向所属类的虚函数表。在程序运行是通过vptr找到对应的虚函数表,并通过表中保存的地址调用相应的函数。

a.虚函数(通过运行阶段才能知道需要调用那个对象); b.纯虚函数; c.虚析构函数; d.虚函数表

4. new/delete是函数吗?它们和malloc/free有何区别?

他们都是用于动态申请内存和释放内存的组合。

  • new操作符从自由存储区上为对象动态分配内存空间,而malloc从堆区上。
  • 使用new创建对象在内存分配时会自动调用构造函数,同时对对象完成动态内存分配和初始化工作,delete也能自动调用析构函数,对对象完成清理与释放内存。而malloc/free不能。
  • new能够自动分配空间大小,new返回的是指定类型的指针,而malloc返回的是 void *类型,需要强制类型转换,并且要指定申请内存大小。
  • new/delete是C++中的运算符,在编译器控制权限之内,malloc/free是C标准库中提供的函数。
5. const和define和inline
  • 作用的阶段:#define是在编译的预处理阶段起作用,而const是在编译、运行的时候起作用。inline内联函数在编译阶段进行替换。
  • 作用的方式:#define只是简单的字符串替换,没有类型检查。而const有对应的数据类型,是要进行判断的,可以避免一些低级的错误。
  • 存储方式:#define只是进行展开,有多少地方使用,就替换多少次,它定义的宏常量在内存中有若干个备份;const定义的只读变量在程序运行过程中只有一份备份。
  • 空间占用:const 常量占用数据段空间。#define 预处理后占用代码段空间。
  • 编译器优化:inline函数可以被编译器优化,而宏定义和const常量则不能。

#define

  • #define是预处理器指令,它在编译之前进行处理。
  • 它将所有出现的宏定义替换为宏定义的值。
  • 没有类型安全检查,因为它只是简单的文本替换。
  • 宏定义不能在条件编译中使用。
  • 宏定义不能在函数内部定义。

const

  • const关键字定义的是常量,它在编译时进行处理。
  • const定义的常量具有数据类型,并且可以进行类型安全检查。
  • const定义的常量可以在条件编译中使用。
  • const定义的常量可以在函数内部定义。

inline

  • inline关键字用于定义内联函数,它在编译时进行处理。
  • 内联函数是一种小的、简单的函数,编译器会尝试将函数调用替换为函数体,以减少函数调用的开销。
  • 内联函数通常用于定义简单的函数,如数学计算函数。
  • 内联函数可以定义在头文件中,并且可以被多个源文件包含。

使用建议

  • 对于需要类型安全检查的常量,使用const
  • 对于简单的、没有类型的常量定义,可以使用#define
  • 对于希望减少调用开销的小函数,使用inline
6. extern和static

extern

  • extern关键字用于声明一个全局变量或函数,它告诉编译器该变量或函数的定义在其他地方。
  • extern变量具有外部链接属性,这意味着它可以被其他文件访问,只要它们通过extern关键字声明。
  • 如果没有使用extern关键字声明全局变量,那么默认情况下它也具有外部链接属性。
  • extern用于在多个文件之间共享全局变量或函数。

static

  • static关键字用于定义静态变量或静态函数。
  • 静态变量具有内部链接属性,这意味着它们只能在定义它们的文件中被访问。
  • 静态变量的存储期是整个程序的执行期间,它们在程序启动时初始化,并在程序结束时销毁。
  • 静态函数也具有内部链接属性,只能在定义它们的文件中被调用。
  • 在函数内部使用static关键字定义的局部变量具有静态存储期,这意味着它们的值在函数调用之间是持久的。

Q1:static修饰全局变量、局部变量和成员变量的区别

Q2:如何引用一个已经定义过的全局变量

(1) 可以引用头文件的方式。假设此变量写错了,那么会在编译期间报错;

(2) extern关键字。假设此变量写错了,那么会在链接期间报错。

Q3:static一个全局变量后再使用extern,在另一个文件中调用时会发生什么?

不会被访问到。static关键字用于限制函数的链接范围。当你在一个源文件中使用static修饰函数时,函数的作用域仅限于这个文件本身,他不能被其他原文件访问到,无论你是否将该函数声明在头文件中还是再使用extern关键字。#include引用头文件不控制链接属性。

  1. 全局变量(无static,有extern):

    • 存储在静态存储区。
    • 可以被程序中的任何函数访问。
  2. 静态全局变量(有static):

    • 存储在静态存储区。
    • 只能在定义它们的文件中访问。
  3. 局部变量(无static,自动存储期):

    • 存储在栈上。
    • 只能在定义它们的函数中访问。
  4. 静态局部变量(有static):

    • 存储在静态存储区。
    • 只能在定义它们的函数中访问,但它们的值在函数调用之间是持久的。
  5. 寄存器变量(有register):

    • 建议存储在寄存器中,但实际存储位置由编译器决定。
    • 只能在定义它们的函数中访问。
  6. 线程局部变量(有_Thread_local):

    • 存储在线程的栈上。
    • 每个线程都有自己的独立副本。
7. class和struct和union

(1) 访问控制:struct成员默认是公开的;class成员默认是私有的。

(2) 成员函数:struct不能包含函数;class可以包含函数。

(3) 面向对象编程:struct不支持面向对象编程的特性;class支持封装、继承和多态。

内存对齐

  • Class:类的成员通常会有对齐填充,以满足最宽成员的对齐要求。类的总大小通常是最大成员对齐要求的倍数。
  • Struct:与类类似,结构体也会有对齐填充,但默认成员是公有的。
  • Union:联合体的内存布局与类和结构体不同,因为它的成员共享内存空间。因此,联合体的大小等于最大成员的大小,而不是所有成员大小的总和。

例如:
 

#include <iostream>

class MyClass {
public:
    int a;
    double b;
    char c;
};

struct MyStruct {
    int a;
    double b;
    char c;
};

union MyUnion {
    int a;
    double b;
    char c;
};

int main() {
    std::cout << "Size of MyClass: " << sizeof(MyClass) << std::endl;
    std::cout << "Size of MyStruct: " << sizeof(MyStruct) << std::endl;
    std::cout << "Size of MyUnion: " << sizeof(MyUnion) << std::endl;
    return 0;
}

在64的系统上,24/24/8

8. friend关键字

用于指定友元类或友元函数,使其可以访问类的私有成员和保护成员。

9. final关键字

当前我这个类就是最终类,我不想让别的类再继承我自己


【看山还是山】

滴答~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值