12.1 类的声明和定义

类是C++里重要的扩展机制,可以提供语言本身不支持的能力,设计良好的类类型使用起来和内置类型一样方便。标准库就是类的一种实际案例,之前的程序里我们使用的vector、string、ostringstream都是标准库给我们定义的类。

1.类的声明

类可以只声明,而不定义,没有定义的类称为不完全类型,比如下面的Animal类,只知道它是个类型,不知道有哪些成员

class Animal;
2.类的定义

类声明的右侧可以直接加一对大括号,完成类的定义,一旦定义完成,类的成员就已经确定,编译器也就能计算存储一个该类类型的对象要多少存储空间。一个类如果在多个文件中定义,必须完全相同。一般来说我们会把定义放到头文件中。以Animal类为例,类定义放到Animail.h中,并使用头文件保护符避免重复定义

#include <string>

#ifndef clazz_animal
#define clazz_animal
class Animal {
public:
    typedef unsigned short age_t;
    Animal() :age(0) {
    }
    void run() const;
    void grow_up() {
        age++;
    }
private:
    std::string name;
    age_t age;
};
#endif // !clazz_animal

类定义时,可以指定成员函数的定义,如grow_up,可以只声明函数,在类的外部再给出函数的定义。在类内部定义的函数默认是内联(inline)的。内联函数能避免方法调用带来的性能损耗,但只适用于实现简单的方法。仅仅完成了声明的成员函数,一般在源文件里定义,这里我们叫Animal.cpp

#include "Animal.h"
#include <iostream>

void Animal::run() const {
    std::cout << "run..." << std::endl;
}
1.类的组成

从类Animal的定义可以看到,类有3类元素组成,类型别名,数据、函数。

  1. 类型别名用来对外隐藏底层使用的类型,在标准库里非常常见,如string::size_type,我们知道它是一个整数,但不知道具体类型
  2. 数据,保存类对象的状态
  3. 函数,提供类对象支持的操作
2.访问标号

控制成员对外部的可见性,支持的标号有3种: public、protected、private。作用和Java里的基本一致。C++有两种定义类的关键字: class、struct。class关键字定义的类默认访问标号是private,struct关键字定义的类默认访问标号是public。

3.不完全类型

最前面我们提到只声明没定义的类是不完全类型。定义不完全类型的数据成员,只能是指向该类类型的指针或引用。当类定义自身类型的数据成员的时候,以为类没有定义完成,也属于不完全类型,因此也只能定义指向自身类型的指针或引用。定义指针或引用的原因是这两种定义不需要调用构造函数。

3. 成员函数
1.构造函数

构造函数是一种特殊的成员函数,函数和类同名,用于对类的数据成员做初始化。如下面的示例,:开始到左大括号{之间的部分,称为初始化列表,初始化列表有字段名和右侧一对小括号组成,小括号的作用是调用数据成员对应类型的构造函数。

Animal() :age(0) {}
2.成员函数

成员函数必须在类内声明,可以在类内、类外定义。类内定义的函数默认是inline函数。在类外定义的函数,函数名之前要使用作用域符::,指定所属类名。

形参表右侧的const将函数声明为常量,函数内部不能修改对象的数据成员。const必须在声明和定义中都出现,否则报错。

void Animal::run() const

类内定义的函数默认是内联(inline)的,如果希望类外定义的函数也是内联,可以只类声明的时候显式的添加关键字inline。内联函数必须对每个源文件可见,因此即使是类外定义的内联函数,通常也和类定义放在一起,即放到头文件里。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值