C++讲解—类(2)
类(2)— 类的分离式编译
当一个类里面定义的成员函数较多的时候,就需要程序员分工合作,那么就可以将函数成员写在类的定义之外,或者干脆分为头文件和源文件,这叫做分离式编译(Separate Compilation)。这是一种将程序的不同部分(通常是不同的源文件)分别编译成目标文件,然后将这些目标文件链接在一起生成最终可执行程序的方法。
1. 类定义外的成员函数定义
如果需要再类之外定义成员函数,就需要在类之内声明函数
// 银行账户类(第3版:分离成员函数的定义)及类的使用例程
// 第一区:预处理指令------------------------------------------------------------
#include <string>
#include <iostream>
using namespace std;
// 第二区:类的声明--------------------------------------------------------------
class Account {string full_name; // 账户名称string number; // 账号long crnt_balance; // 账户余额public://如果需要再类之外定义成员函数,就需要在类之内声明函数// 构造函数声明Account(string name, string num, long amnt);// 成员函数声明string name() { return full_name; } // 返回账户名称string no() { return number; } // 返回账号long balance() { return crnt_balance; } // 返回账户余额void deposit(long amnt); // 存入void withdraw(long amnt); // 取出
};// // 第三区:定义函数区------------------------------------------------------------
// 构造函数定义
Account::Account(string name, string num, long amnt) {full_name = name; // 账户名称number = num; // 账号crnt_balance = amnt; // 账户余额
}// 存入函数定义
void Account::deposit(long amnt) {crnt_balance += amnt;
}// 取出函数定义
void Account::withdraw(long amnt) {crnt_balance -= amnt;
}
// 第四区:主函数区------------------------------------------------------------
int main() {Account liyang("李阳", "12345678", 1000); // 李阳的账户Account zhouyan("周燕", "87654321", 200); // 周燕的账户liyang.withdraw(200); // 李阳取出200元zhouyan.deposit(100); // 周燕存入100元cout << "■李阳的账户:" << liyang.name() << " (" << liyang.no()<< ") " << liyang.balance() << "元\n";cout << "■周燕的账户:" << zhouyan.name() << " (" << zhouyan.no()<< ") " << zhouyan.balance() << "元\n";
}
2. 头文件与源文件的分离
创造类,就相当于创造了一个工具。如果后续有人想使用这个工具,那么这个工具的使用方法是怎样的呢?
如果我们想象类是一个鼠标键盘音箱类的电子设备,那么我们可以看到,这些设备的有一个本体,本体是由 外壳 包括着各类芯片,有一个接口,一般是蓝牙链接或者有线链接。那么类的设计也是有接口外壳 和芯片电路之分的,类的头文件便是整体的外壳+连接口,类的源文件便是里面的芯片。
1. 类的头文件
在C++原则上,不能在头文件中放置 using 指令。因为使用者哎使用这个类的时候,会将自己文件中的using指令和头文件中的using指令混淆,不同库或模块中的同名实体发生冲突,从而引发编译错误或运行时错误。
所以这个头文件代码里面的string都要写为std::string.
// 银行账户类(第4版:头文件)
#include <string>class Account {std::string full_name; // 账户名称std::string number; // 账号long crnt_balance; // 账户余额public:Account(std::string name, std::string num, long amnt); // 构造函数std::string name() { return full_name; } // 返回账户名称std::string no() { return number; } // 返回账号long balance() { return crnt_balance; } // 返回账户余额void deposit(long amnt); // 存入void withdraw(long amnt); // 取出
};
2. 类的源文件
// 银行账户类(第4版:源文件)
#include <string>
#include <iostream>
#include "Account.h"#在这里需要声明头文件using namespace std;#在这里使用using指令// 构造函数
Account::Account(string name, string num, long amnt) {full_name = name; // 账户名称number = num; // 账号crnt_balance = amnt; // 账户余额
}// 存入
void Account::deposit(long amnt) {crnt_balance += amnt;
}// 取出
void Account::withdraw(long amnt) {crnt_balance -= amnt;
}
3. 类的使用
在使用类的过程中,p 是一个指向 Account 类型的指针。在函数 print_Account 的参数列表中,Account* p 表示这个函数接受一个指向 Account 类型对象的指针。通过使用指针,print_Account 函数可以灵活地处理不同的 Account 对象,而不需要为每个对象创建副本,从而提高代码的效率和可读性。
// 银行账户类(第4版)的使用例程
#include <string>
#include <iostream>
#include "Account.h"using namespace std;// 显示 p 所指的 Account 的账户信息(账户名称、账号、账户余额)
void print_Account(string title, Account* p) {cout << title<< p->name() << " (" << p->no() << ") "//p->name 用于通过指针访问对象的成员。<< p->balance() << "元\n";
}int main() {Account liyang("李阳", "12345678", 1000); // 李阳的账户Account zhouyan("周燕", "87654321", 200); // 周燕的账户liyang.withdraw(200); // 李阳取出200元zhouyan.deposit(100); // 周燕存入100元print_Account("■李阳的账户:", &liyang);//&liyang 是获取 liyang 对象的地址,并将其传递给 print_Account 函数的 p 参数。print_Account("■周燕的账户:", &zhouyan);
}