天天看点

C/C++基础 -- 类的定义与实现(2):类的数据成员、类的成员函数、类的声明1、类的数据成员2、类的成员函数3、类的声明

C/C++基础 -- 类的定义与实现(2):类的数据成员、类的成员函数、类的声明

  • 1、类的数据成员
    • 1.1、在类中声明数据成员
    • 1.2、在类中定义或声明数据类型
  • 2、类的成员函数
    • 2.1、在类外部定义成员函数
    • 2.2、定义类成员函数的几点说明:
    • 2.3、内联成员函数
    • 2.4、成员函数重载及默认参数
    • 2.5、成员函数的存储方式
  • 3、类的声明
本博文由 西北工业大学MOOC 总结而来,以备以后回顾。(侵删)

1、类的数据成员

1.1、在类中声明数据成员

  类的数据成员声明类似于普通变量的声明。如果一个类具有多个同一类型的数据成员,则这些成员可以在一个成员声明中指定:

C/C++基础 -- 类的定义与实现(2):类的数据成员、类的成员函数、类的声明1、类的数据成员2、类的成员函数3、类的声明

  类的数据成员可以是基本类型、数组、指针、引用、共用体、枚举类型、void指针、const限定等数据类型。大部分C++数据类型都可以作为类的数据成员:

C/C++基础 -- 类的定义与实现(2):类的数据成员、类的成员函数、类的声明1、类的数据成员2、类的成员函数3、类的声明

  类的数据成员还可以是成员对象(member object),即类类型或结构体类型对象。若类A中嵌入类B的对象,称这个对象为子对象(subobject)。如:类Line中嵌入了类Point的子对象start、end。

C/C++基础 -- 类的定义与实现(2):类的数据成员、类的成员函数、类的声明1、类的数据成员2、类的成员函数3、类的声明

1.2、在类中定义或声明数据类型

  除了定义数据成员和成员函数以外,类还可以定义自己的局部类型,并且使用类型别名来简化。

  在类中定义或声明的数据类型的作用域是类内部,因此,它们不能再类外使用。

  类定义中,可以定义结构体和共用体类型、嵌套的类定义,声明枚举类型。

C/C++基础 -- 类的定义与实现(2):类的数据成员、类的成员函数、类的声明1、类的数据成员2、类的成员函数3、类的声明

2、类的成员函数

2.1、在类外部定义成员函数

  如果成员函数仅有声明在类定义中,则在类的外部必须有它的实现,其一般形式为:

C/C++基础 -- 类的定义与实现(2):类的数据成员、类的成员函数、类的声明1、类的数据成员2、类的成员函数3、类的声明

定义成员函数例子:

C/C++基础 -- 类的定义与实现(2):类的数据成员、类的成员函数、类的声明1、类的数据成员2、类的成员函数3、类的声明

2.2、定义类成员函数的几点说明:

一、作用域限定符(::)

  (::)是作用域限定符(field qualifed)。如果在作用域限定符前没有类名,或者函数前面既无类名又无作用域限定符,如:

C/C++基础 -- 类的定义与实现(2):类的数据成员、类的成员函数、类的声明1、类的数据成员2、类的成员函数3、类的声明

  则表示set函数不属于任何类,这个函数不是成员函数,而是全局普通函数。此时的(::)不是类作用域限定符的含义,而是命名空间限定符的含义。

二、 在成员函数中可以访问中这个类的任何成员,无论它是公有的或是私有的,是类内部声明的还是类外部定义的。

三、 虽然成员函数在类的外部定义,但在调用成员函数是会根据类中声明的函数原型找到函数定义(即函数代码),从而执行该函数。因此,类的成员函数原型声明必须出现在成员函数定义之前,否则会编译出错。

四、 养成良好的编程习惯:在类的内部声明成员函数,而在类的外部定义成员函数。这样可以减少类体的长度,使类体结构清晰,便于阅读,而且有助于类的接口和实现分离。

五、 如果一个成员函数体不太复杂,只有4~5行是,一般可在类体中定义。

2.3、内联成员函数

(内联函数讲解链接:https://blog.csdn.net/weixin_43569276/article/details/99986575)

  类的成员函数可以指定为 inline,即内联函数。

  默认情况下,在类体中定义的成员函数若不包括循环等控制结构,符合内联函数要求是,C++会自动将它们作为内联函数处理(隐式内联)。

  同时也可以显式地定义内联函数:

C/C++基础 -- 类的定义与实现(2):类的数据成员、类的成员函数、类的声明1、类的数据成员2、类的成员函数3、类的声明

判断成员函数为内联函数的四个条件:

  1. 符合内联函数的要求;
  2. 符合 1 的条件,并且在类体中定义,则会自动成为内联函数;
  3. 符合 1 的条件,在类体中显式指明inline,或在外部定义时显式指明inline,或者内部声明和外部定义同时显式指明,则函数是内联的。
  4. 在类外部定义,并且既没有在类体,也没有在外部定义时显式指明inline,则函数不是内联的。

2.4、成员函数重载及默认参数

  可以对成员函数重载或使用默认函数。例如:

C/C++基础 -- 类的定义与实现(2):类的数据成员、类的成员函数、类的声明1、类的数据成员2、类的成员函数3、类的声明

  需要注意,声明成员函数的多个重载版本或指定成员函数的默认参数,只能在类的内部进行。

  因为类定义中的声明先于成员函数的外部实现,根据重载或默认参数函数的要求,必须在第一次在类内部出现函数声明定义是就明确函数是否有重载或有默认参数。

2.5、成员函数的存储方式

  用类实例化一个对象时,系统会为每一个对象分配存储空间。如果一个类包括了数据成员和成员函数,则要分别为数据和函数的代码分配存储空间。

  通常,C++会为每个对象的数据成员分配各自独立的存储空间,像结构体成员那样。

  对于同一类的不同对象,成员函数的存储方式如下:

C/C++基础 -- 类的定义与实现(2):类的数据成员、类的成员函数、类的声明1、类的数据成员2、类的成员函数3、类的声明

  由于不论调用哪一个对象的函数代码,实际调用的都是同样内容的代码,所以,成员函数代码只有公用的一段存储空间,调用不同对象的成员函数时都是执行同一段函数代码。

例: 定义如下一个类:

C/C++基础 -- 类的定义与实现(2):类的数据成员、类的成员函数、类的声明1、类的数据成员2、类的成员函数3、类的声明

  sizeof(Time)的值是12。显然,Time类的存储空间长度只取决于数据成员h、m、s所占的空间(未实体化的类使用sizeof(),是有值的。因为要实体化就要占用一定的存储空间),而与成员函数settime无关。C++把成员函数的代码存储在对象空间之外的地方。

3、类的声明

  在一个给定的源文件中,一个类只能被定义一次。

  实际编程中,通常将类的定义放在头文件中,这样可以保证每个使用该类的文件都以同样的方式定义类。

  可以声明一个类而不去定义它:

C/C++基础 -- 类的定义与实现(2):类的数据成员、类的成员函数、类的声明1、类的数据成员2、类的成员函数3、类的声明

  该声明称为前向声明(forward declaration),表示在程序中引入了Point类类型。

  在前向声明之后,定义之前,类Point是一个不完全类型(包含的成员未定)。因此不能定义该类型的对象,只能用于定义指向该类型的指针及引用,或者用于声明使用该类型作为形参类型或返回类型的函数。

  此外,类不能具有自身类型的数据成员。然而,类名一经出现就可以认为该类已经声明。因此,类的数据成员可以是指向自身类型的指针或引用。

例:

C/C++基础 -- 类的定义与实现(2):类的数据成员、类的成员函数、类的声明1、类的数据成员2、类的成员函数3、类的声明