类(一)
1.类方法可以直接访问类的private组件(p283);对于类的私有部分,在其中声明的成员只能通过成员函数进行访问;对于类的公有部分,在其中声明的成员可被使用类对象的程序直接访问。p287
2.定义位于类声明中的函数都将自动成为内联函数,在类声明中定义方法等同于用原型替换方法定义,然后在类声明后面将定义改写为内联函数。因此类声明中常将短小的成员函数作为内联函数。p285
3.创建的每个新对象都有自己的存储空间,用于存储其内部变量和类成员;但一个类的所有对象共享同一组类方法,即每种方法只有一个副本。p285
4.如果没有为类提供任何构造函数,则C++将自动提供默认构造函数;它是默认构造函数的隐式版本,不做任何工作。如一个类human的默认构造函数:
Human::Human(){}
当且仅当没有定义任何构造函数时,编译器才会提供默认构造函数。为类定义了构造函数后,程序员就必须为它提供默认构造函数。如果要创建对象,而不显示地初始化,则必须定义一个不接受任何参数的默认构造函数。
定义默认构造函数的方式有两种:p290
1)给已有的构造函数的所有参数提供默认值。(通常做法)
2)通过函数重载来定义另一个构造函数--一个没有参数的构造函数。
5.类对象过期时,程序将自动调用析构函数。如果构造函数使用new来分配内存,则析构函数中必须使用delete来释放这些内存。p290
6.const成员函数 p295
const成员函数用来保证函数不会修改调用该成员函数的对象。构造const成员函数的方法是将const关键字放在函数括号的后面。即一个成员函数show()的定义和声明应该类似于:
//声明 void show() const; //定义 void stackname::show() const { ... }
一般地,只要类方法不修改调用该方法的对象,就应该将其声明为const。
7.this指针
this指针被作为隐藏参数传递给类的方法;this指针指向调用成员函数的对象,即this指针是调用成员函数对象的地址。(*this即调用成员函数的对象,this是该对象的地址,该不是该对象本身)p297
8.要创建类对象数组,该类必须有默认构造函数;因为若要创建对象而不将其显示地初始化,必须定义一个不接受任何参数的构造函数。p301
9.类作用域 p302
在类中定义的名称(如类的数据成员名类成员函数名)的作用域都为整个类,作用域为整个类的名称只有在该类中是已知的,在类外是不可知的。
因此,类作用域意味着不能从外部直接访问类的成员和共有成员函数,即
1)要调用共有成员函数,必须通过对象
2)定义成员函数时,必须使用作用域解析运算符,如
void Stock::ipdate(double price) { ... }
3)在类声明或成员函数定义中,可以使用未修饰的成员成名(即不加作用域解析运算符的成员名称)。
10.作用域为类的常量--创建一个由所有类共享的常量 p303 (p349 类的静态成员变量)
两种方法:
1)在类中声明一个枚举
class Bakery { private: enum {Months = 12}; double costs[Months]; ... };
用这种方式声明枚举并不会创建类数据成员。即,所有的对象中都不包含枚举;Months 只是一个符号名称,在作用域为整个类的代码中遇到它时,编译器用12来替换它。
2)使用关键字static来在类中定义被所有该类对象共享的常量
class Bakery { private: static const int Months = 12; double costs[Months]; ... }
上述代码创建一个名为Months的常量,该常量与其他静态变量存储在一起。因此,只有一个Months常量,被所有的Bakery类对象共享。
11.通常,将类声明分成两部分组成;类声明(包括由函数原型表示的方法)应放到头文件中;定义成员函数的源代码放在方法文件.cpp中 p307
stack.h 中存放类声明,成员数据,成员函数的原型
// stack.h -- class definition for the stack ADT #ifndef STACK_H_ #define STACK_H_ typedef unsigned long Item; class Stack { private: enum {MAX = 10}; // constant specific to class Item items[MAX]; // holds stack items int top; // index for top stack item public: Stack(); bool isempty() const; bool isfull() const; // push() returns false if stack already is full, true otherwise bool push(const Item & item); // add item to stack // pop() returns false if stack already is empty, true otherwise bool pop(Item & item); // pop top into item }; #endif
stack.cpp 中实现stack类的成员函数
// stack.cpp -- Stack member functions #include "stack.h" Stack::Stack() // create an empty 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 = items[--top]; return true; } else return false; }
stacker.cpp 使用类
// stacker.cpp -- testing the Stack class #include <iostream> #include <cctype> // or ctype.h #include "stack.h" int main() { using namespace std; Stack st; // create an empty stack char ch; unsigned long po; cout << "Please enter A to add a purchase order,\n" << "P to process a PO, or Q to quit.\n"; while (cin >> ch && toupper(ch) != 'Q') { while (cin.get() != '\n') continue; if (!isalpha(ch)) { cout << '\a'; continue; } switch(ch) { case 'A': case 'a': cout << "Enter a PO number to add: "; cin >> po; if (st.isfull()) cout << "stack already full\n"; else st.push(po); break; case 'P': case 'p': if (st.isempty()) cout << "stack already empty\n"; else { st.pop(po); cout << "PO #" << po << " popped\n"; } break; } cout << "Please enter A to add a purchase order,\n" << "P to process a PO, or Q to quit.\n"; } cout << "Bye\n"; return 0; }
头文件中常包含的内容:
1)函数原型
2)使用#define或const定义的符号常量
3)结构声明
4)类声明
5)模板声明
6)内联函数