12 类

1. 类的定义和声明

  1. 一旦类定义完成后,就没有任何方式可以增加成员了。

  2. 在类内部定义的成员函数(函数实现体在类中),则会认为是inline成员函数(该函数被调用时直接换成函数体)

  3. 不完全类型:声明了该类,在定义该类之前,成为不完全类型:
    • 只有当类定义体完成之后才能定义类,所以类不能具有自身类型的数据成员(因为该类定义还没有完成,不知道存储该类的对象所需的空间,无法完成初始化)
    • 类数据成员可以是指向自身类型的指针或引用,因为指针或者引用仅仅是一个地址空间或者别名,所以分配空间与该类无关,所以可以有。
  4. 类的定义必须以分号结束,因为类的定义之后可以接受对象定义列表。
  5. mutable关键字: 数据成员是可变的(在const成员函数内也可变)。

2. this指针

  1. this指针和调用成员函数的对象绑定在一起;

  2. this指针是一个const指针,即指针本身不能改变,但是指向的内容可以改变(易理解,this和对象关联,对象本身在函数调用过程中不能改变,但是对象中的数据成员可以改变)

    • const 成员函数不能改变其所操作的对象的数据成员,是只读函数。并且必须在声明和定义中均出现,不然会有编译错误。
    • 由上知,const成员函数既不能改变this所指内容,也不能改变this地址。

3. 类作用域

  1. 在类作用域外(即分号结束),定义类的数据成员和函数定义均需要指明属于哪个类(完全限定名)

    • 形参和函数体中可以不指明类直接用类的数据成员,因为函数名字已经指明了属于哪一个类;
    • 函数返回类型在函数名之前,在遇到函数返回类型的时候不知道属于哪个类,所以如果函数返回类型用到了类中定义的某一个类型,则需要指明完全限定名。
  2. 类定义分为两个阶段:

    • 编译成员声明;
    • 只有在所有成员出现之后,编译它们的定义本身。
  3. 名字查找

    • 在改名字的块(函数作用域)中查找;
    • 在所属类成员(类作用域)的声明;
    • 在外围作用域查找(如全局变量)等等。

4. 构造函数

  1. 构造函数不能声明为const类型, 因为const函数除mutable数据成员外其他数据成员是不可改变的,而构造函数就是给成员函数赋值的,两者相悖,所以error。

  2. 构造函数过程:

    • 初始化阶段(初始化列表),也就是为各个数据成员分配相应的空间;
    • 普通计算阶段(函数体中的操作,如给数据成员赋值等)。
      由上可知,类数据成员初始化化完成之后才会进入构造函数函数体中。
  3. 必须使用初始化列表的情况:

    • 任何const成员数据,因为const变量一旦确定不能改变,则必须在初始化时确定,在普通计算阶段(构造函数体内)进行赋值操作时不可以的;
    • 引用类型成员, 因为引用是别名,则定义引用时必须初始化,在函数体中直接赋值时该引用必须是已经定义过得,所以引用也必须在初始化列表中;
    • 没有默认构造函数的类类型的成员,如果没有为类成员提供初始化式,则编译器将会调用。
  4. 数据成员在初始化次序与其声明顺序有关,与在初始化列表中的顺序无关。

  5. 如果类包含内置或复合类型的成员,则该类应该定义自己的构造函数来初始化这些成员。

  6. 抑制构造函数的隐式转化,使用explicit关键字
class A{
    A(string str);
    bool isSame(A&);
}
string str = "str";
A a = new A("aaa");
a.isSame(str);//会隐式的将string类型转化为A对象,进行判断。但是这个往往会造成误区,所以用explicit关键字来说明参数不接受隐式转化, explicit bool isSame(A&)

5. 友员

  1. 为了实现一个类使用另一个类的私有成员。

  2. 例子:

class A{
    friend class B;  //B可以用A中的私有成员和函数,但B不是A的数据成员
    friend int C::get();  // C的get方法可以用A中的私有成员和函数,但此函数不是A的成员函数
}
  • 必须先定义包含成员函数的类,才能将成员类或者函数定义为友元。即必须定义A,才能定义B和C。因为B和C中依赖A中定义的成员。
  • 但是它们的声明没有限制。

6. static类成员

  1. 与类有关,与类对象无关;
  2. 优点:

    • 在类作用域中,避免与其他变量名冲突;
    • 封装,只与该类有关;
    • 可以用于存储和类对象无关的成员,意图明确。如Thread类中的sleep()函数。
  3. 没有this指针

  4. const static成员,可以在类的定义体重初始化,但是仍需在类外进行定义。普通成员不行。
  5. static数据成员的类型可以是该成员所属的类型,因为static成员独立于任何对象而存在,不是类类型对象的组成部分。(非static必须是指针或引用)
class A{
    static A a; //ok
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值