C++类细节,反汇编

2. 虚函数vs纯虚函数

  • virtual修饰的成员函数就是虚函数,它允许在子类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和子类的同名函数。引入虚函数是为了动态绑定。
  • 纯虚函数除了关键字virtual外,还要 =0, 它是在基类中声明但没有定义的虚函数,要求子类必须提供实现。引入纯虚函数是为了派生接口,即子类仅仅只是继承函数的接口。

3. 重写vs重载vs隐藏

  • 重写:发生继承关系中,子类重写父类的方法。
  • 重载:发生在同一个类中,函数名相同,但参数个数或类型不同。
  • 隐藏:子类函数屏蔽了与其同名的基类函数,有以下两种情况:
    1、参数不同,基类函数被隐藏 (而不是重载)
    2、参数相同,但基类函数没有virtual关键字,基类函数被隐藏 (而不是重写)

3.1. 为什么C++可以重载?

  • C++引入了命名空间,以及作用域,比如类作用域,命名空间作用域。
  • 函数在编译期间,链接符号的时候,会在符号后追加一些特殊标识,比如add函数,变成add@123。

4. struct vs union

  • 相同:都可以将不同类型的变量组合成一个整体。
  • 区别
    • struct 里的每个成员都有自己独立的内存空间;sizeof(struct) 是内存对齐后所有成员长度的总和。
    • union 里的所有成员共享同一内存空间;sizeof(union) 是内存对齐后最大的数据成员长度。

4.1. 为什么要内存对齐?

  • 确保代码在不同平台上的兼容性。
  • 提高内存访问的效率。
  • ps:在Visual Studio中,默认对齐值8,将它与结构体中最大的数据成员长度进行比较,取两者的较小值,设定为实际对齐值。

5. static作用

  • static修饰的成员变量就是类变量,是类的所有对象共有的。
  • static修饰的成员函数就是类方法,类方法不能访问对象变量只能访问类变量,可以由类名直接调用,也可以由对象调用。
  • static修饰的局部变量就是局部静态变量,在函数内可以访问到。
  • static修饰的全局变量就是全局静态变量,是当前文件内可以访问到。
  • ps:对象变量,是每个对象单独拥有的。
  • ps:const强调值不能被修改,而static强调内存只有一份拷贝。

6. 空类vs空结构体

  • 空类:默认private。
  • 空结构体:默认public。

6.1. 八个默认函数:

  • 构造函数 【A();】
  • 析构函数 【~A();】
  • 拷贝构造函数 【A (const A&);】
  • 重载赋值运算符 【A&operator = (const A&);】
  • 重载取址运算符 【A* operator& ();】
  • 重载取址运算符const 【const A* operator& () const;】
  • 移动构造函数(C++11) 【A(A&&);】
  • 重载移动赋值运算符(C++11)【A& operator = (const A&&);】

6.2. 为什么空类占用1字节

  • 因为如果对象完全不占用内存空间,空类就无法取得实例的地址,this指针失效,因此不能被实例化。而类的定义是由数据成员和成员函数组成的,在没有数据成员情况下,还可以有成员函数,因此仍然需要实例化。

7. const作用

  • 限定变量不可修改。
  • 限定成员函数不可修改数据成员(后置const)。
  • 成员函数的返回值类型是const,则返回值不是左值(前置const)。
  • 用const对函数的参数修饰,表面是输入参数,在函数内不可写。
  • const函数只能调用const函数,非const函数可以调用const函数。

7.1 指针常量vs常量指针vs常量指针常量

  • 指针常量,即指针本身是常量,所以指针的值(内存地址)不能改变,示例如下。
    int a = 10, b = 20;
    int* const p= &a;
    p = &b;  //错误,指针存放的内存地址不可变
    *p= 100; //正确,内存地址存放的内容可以改变
  • 常量指针,即指向常量的指针,不能通过指针修改指向的内容,示例如下。
    const int a = 10;
    int b = 20;
    const int* p = &a;
    p = &b; //正确, 指针存放的内存地址可变
    *p = 100; //错误,指针指向的内容不可变
    b = 100; //正确,可以通过原来的声明修改
  • 常量指针常量,即指向常量的指针本身也是常量,不能通过指针修改指向的值,指针的值不能改变,示例如下。
    const int a = 10;
    int b = 20;
    const int* const p = &a;
    p = &b; //错误, 指针存放的内存地址不可变
    *p = 100; //错误,指针指向的内容不可变

8. 接口vs抽象类

  • 抽象类:带有纯虚函数的类。
    抽象类作用:为了扩展和重用。
  • 接口:没有数据成员;成员函数都是公有的、都是纯虚函数,虚析构函数除外;是完全抽象的类。
    接口作用:只提供了一种规范,实现接口的类必须实现接口中的所有方法。
  • 相同:都不能实例化,但可以创建指针。
  • 代码如下。
// ConsoleApplication5.cpp : 此文件包含 "main" 函数。程序执行将在此处开始
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值