吉林大学面向对象编程笔记(3)类型与变量

109 阅读3分钟

类型与变量

抽象数据类型(Abstract Data Type)

ADT:数学模型+可施加其上的操作集合。(类型名称,数据集,数据间的关系,操作集)

  • 与具体表示无关

  • 与现实世界无关

  • 任意性和无穷性

    a ADT :name { 数据: 关系: 操作:}

    eg

    Person {
      数据: 
      age
      关系:
      age>=0
      操作:
      birth 
      grow
      dead}
    ​
    

C++中的类型

  1. 内置类型

    • 基本类型

      char , wchar_t(宽字符), int, float,(void)

    • 扩展(扩充类)类型

      <类型修饰> 基本类型类型修饰

      short、long、signed、unsigned、double

      例: long int,unsigned long int,double float,long double, ...F() { int a = 10;}

    • bool型 非零=true,零=false

    • C++1z新增类型:如 long long ,编译期推导类型(auto,decltype)

      • auto: int a = 10; auto b=a+99;
      • decltype: int a = 10; decltype(sqrt(a)) b=sqrt(a+99)+1;
  2. 自定义类型

    • 使用typedef/using定义的

      • 定义类型格式:typedef <已知类型> <新类型>

      • 定义函数类型格式: typedef ReturnType (*新类型)(参数列表);

        typedef本质上没有增加新类型

    • 枚举类型

      enum 枚举类型名 {枚举值列表 };

      枚举值必须是整数第一个枚举值,缺省为0后一个枚举值,若没有指定,则为前一个枚举值+1

      enum class 枚举类名 { 枚举值列表 };

      枚举值可以指定类型、指定数值枚举值不再允许与int随意转换、比较使用时必须指明scope(即枚举类名)

      enum class AAA : unsigned int  {
                      A    = 'a' ,
                      EF = 120
              };
      int main( )  {
              cout<< (int)(AAA::A)<<endl;
              cout<< (int)(AAA::EF)<<endl;
              return 0;
          }
      ​
      
    • 使用class,stuct,union定义的

  3. 导出类型

    • 数组

      例: int a[5]; MyClass objs[3];

    • 指针

      例: int * p = 0; MyClass * pobjs[4]; int **pp = &p;

    • 引用

      例: int a =100; int & b = a;(左值引用)

      右值引用(C++1xyz): T f( ) { return T(); } T && t=f( );

      • 在这个例子中,我们有一个函数 f(),它返回类型为 T 的对象。根据 C++11 及以后的标准,函数 f() 返回的是一个右值(rvalue)。右值是一个临时的、即将被销毁的值,可以被移动(move)或者转移(forward)。

        接下来,我们有一行代码 T && t = f();。这里的 T && 是一个右值引用类型(rvalue reference)。右值引用是 C++11 引入的一种新类型,用于绑定到右值。右值引用可以用来实现移动语义,允许我们对右值进行资源的高效转移而不是拷贝。

        在这个例子中,函数 f() 返回的右值将被绑定到右值引用 t 上。这意味着 t 将成为该右值的一个别名,并且可以通过 t 来访问该右值。

        总结起来,这段代码的作用是调用函数 f() 并将其返回的右值绑定到右值引用 t 上,以便我们可以在后续的代码中使用 t 来操作该右值。这种用法通常用于实现移动语义,以提高程序的性能和效率。

    • 声明

      解释说明一个编译单元中一个名字的含义和属性。

      extern int a;           // 声明外部整型变量a
      extern const int c;         // 声明外部整型常量c
      int f(int);             // 声明函数f
      struct S;           // 声明结构S
      typedef int Int;        // 声明类型 Int
      extern X anotherX;  // 声明外部变量anotherX
      using N::d;             // 声明名字d
    • 定义:

      一个声明同时也是一个定义,当具有:确定的函数体、确定的类内容、具体值、 确定存储空间、确定别名等时

      • 变量的定义:

        • C++98: 格式: [<存储类>]<类型><变量名表>[=初始化表];

        • C++11: 新增: [<存储类>]<类型><变量名表>[{初始化表}];

          eg val2{weight}

    声明和定义的使用

    • 就近原则(现使用,现定义)

    • 先声明,后使用

    • 单一定义规则

      • 头文件中可放声明,以及类定义,但不应放变量定义和函数定义
      • 函数定义及变量定义,只能在整个工程中定义一次
  4. 模板类型(泛型)

存储空间(storage duration)

image-20230624125752664

作用域

  • 全局作用域

  • 文件作用域

  • 块级作用域

  • 类级作用域

  • 名字空间作用域

    image-20230624140129101

表达式相关概念

  • 一般表达式和返回值

  • for循环中的表达式:

    for(初值表达式;条件表达式;步进表达式)

  • 逗号表达式:

    例: x=100, y=x-1000;

  • 条件表达式:

    例: if (表达式1 && 表达式2){…}

  • 赋值表达式

    例: x=y=100+f(5);

  • 左值表达式:

    能够作为=号的左侧表达式,也可以作为右侧表达式

  • 右值表达式:

    只能作为=号的右侧表达式(C++1z)

  • Lambda表达式代表的是一个匿名(无名)的函数。

    lambda表达式通用格式:

    [capture ] ( params ) mutable exception attribute -> ret { body }

    简化格式1: [capture ] ( params ) -> ret { body }

    简化格式2: [capture ] ( params ) { body }省略了返回值类型的 lambda 表达式,函数返回值类型由body自动推演出来。

    简化格式3: [capture ] { body }省略了参数列表,类似于无参函数 f( )。

    • mutable 修饰符表明body内的代码可以修改被捕获(capture)的变量,并且可以访问被捕获对象的 non-const 方法。

    • exception 说明 lambda 表达式是否抛出异常(noexcept),以及抛出何种异常,类似于void f() throw(X, Y)。

    • attribute 用来声明属性。

    • retType指明返回类型,可以明确地指定,如int,bool,自定义类型等,也可以是decltype推演类型。

    • capture 指定了body中可以访问的外部变量列表,具体解释如下:

      • [a,&b]以传值的方式捕获a变量,以引用的方式捕获b变量。
      • [this] 以传值的方式捕获 this 指针。
      • [&] 以引用的方式捕获所有的外部自动变量,可修改外部量。
      • [=] 以传值的方式捕获所有的外部自动变量,不可修改外部量。
      • 不捕获外部的任何变量。