对象和类
- 面向对象编程(OOP)是一种特殊的、设计程序的概念性方法。最重要的OOP特性:
1. 抽象和类
- 在C++中,用户定义类型指的是实现抽象接口的类设计。
- 指定基本类型完成的3项工作(内置类型有关操作被内置到编译器中,用户自定义的类型则必须自己提供这些信息):
- 决定数据对象需要的内存数量。
- 决定如何解释内存中的位。
- 决定如何使用数据对象执行的操作或方法。
- 一般类说,类的规范由两个部分组成(声明提供蓝图,定义提供细节):
- 类声明:以数据成员的方式描述数据部分,以成员函数的方式描述公有接口。
- 类方法的定义:描述如何实现类成员函数。
- 类中封装的体现:
- 数据隐藏:将数据放在私有部分中,防止程序直接访问数据。
- 实现细节与抽象(公有接口)分开。
- 类声明与类定义放在不同文件中。
- C++通常使用类来实现类描述,而把结构限制为只表示纯粹的数据对象或没有私有部分的类。
- 定义位于类声明中的函数都将自动成为内联函数,一般将短小的成员函数作为内联函数。在类声明外定义的成员函数,要成为内联函数则须在定义时使用
inline
限定符。
- 类声明的典型格式:
class className
{
// 数据隐藏:数据封装到私有部分
private:
// data member declarations
// 类设计的抽象部分——公有接口
public:
// member function prototypes
}
2. 类的构造函数和析构函数
- C++提供了一个特殊的成员函数——类构造函数,专门用于构造新对象、将值赋给它的数据成员。
- C++使用构造函数初始化对象的两个方式:
- 显示调用构造函数(注意,这种方式C++可能会创建一个临时对象然后将值复制给food,随后调用临时对象的析构函数)
Stock food = Stock("World", 250, 1.25);
Stock food("Furry", 50, 2.5);
- 当且仅当没有定义任何构造函数时,编译器才会调用默认构造函数。
- 析构函数的调用:
- 静态存储类对象:在程序结束时自动调用。
- 自动存储类对象:在程序执行完代码块自动被调用。
- 通过
new
创建的类对象:当使用delete
释放内存时自动被调用。
- 临时对象:程序在结束对该对象的使用时自动调用其析构函数。
- 可以通过初始化也可通过赋值来设置对象的值,则应采用初始化方式,通常这种方式效率更高。
-
const
成员函数,用于确保函数不会修改调用对象,声明格式如下:
// 声明
void show() const;
// 定义
void Stock::show() const
{
// 实现
}
-
注意:接受一个参数的构造函数允许使用赋值句法来将对象初始化为一个值。
className object = value;
3. this指针
- 所有的类方法都将this指针设置为调用它的对象地址。
4. 对象数组
// 对象数组声明
Stock myStuff[4]; // 创建一个包含4个Stock对象的数组
// 对象数组初始化:使用不同的构造函数
// stocks[3]和stocks[4]将使用默认构造函数初始化
Stock stocks[5] = {
Stock("nanoSmart", 12.5, 20),
Stock("Boffo objects", 200, 20),
Stock()
};
- 初始化对象数组的方案是,首先使用默认构造函数创建数组元素,然后花括号中的构造函数将创建临时对象,然后将临时对象的内容复制到相应的元素中。警告:要创建类对象数组,则这个类必须有默认的构造函数。
5. 类作用域
// 类中声明常量
class Stock
{
private:
// 1. 使用枚举
enum { LEN = 30 };
// 2. 使用关键字static
static const int LEN2 = 50;
const int LEN3 = 40; // 错误!!!类声明不会分配内存。
}
6. 抽象数据类型
-
抽象数据类型(abstract data type, ADT):以通用的方式描述数据类型,而没有引入语言或实现细节。堆栈示例(通过
typedef
隐藏数据类型,后续可与模板进行比较):
// stack.h -- ADT堆栈类定义
#ifndef STACK_H_
#define STACK_H_
typedef unsigned long Item;
class Stack
{
private:
enum { MAX = 10 };
Item items[MAX];
int top;
public:
Stack();
bool isempty() const;
bool isfull() const;
bool push(const Item& item);
bool pop(Item& item);
};
#endif
// stack.cpp -- Stack类实现
#include "stack.h"
Stack::Stack()
{
top = 0;
}
bool Stack::isempty() const
{
return top == 0;
}
bool Stack::isfull() const
{
return top == MAX;
}
bool Stack::push(const Item& item)
{
if(top < MAX)
{
items[top++] = item;
return true;
}
else
return false;
}
bool Stack::pop(Item& item)
{
if(top > 0)
{
item = item[--top];
return true;
}
else
return false;
}