|
类通常的组织方式:接口和实现。
类的接口是指类的声明,实现是指类的成员函数的定义。
在c++程序中,常把接口放在一个与类同名的头文件中,类的实现放在一个与类同名的源程序中。
头文件
以源代码的形式提供给用户,用户可以用#include宏把头文件包含到自己的程序中。
头文件中的信息对用户是可见的,包含:常量定义,类型定义,名字声明,枚举,宏定义,条件编译指令,函数声明,内置函数定义,模板声明或模板定义以及注释等内容。
对于类,常把类的定义放在头文件中,用户可以了解类的全部成员,定义类对象,使用类。
例如:类的定义放在单独的头文件Stack.h中
//堆栈stack的头文件:Stack.h
#ifndef Stack_h #define Stack_h class Stack{ private: int *data; int count; int size; public: Stack(int Stacksize=10); ~Stack(); void Push(int x); int Pop(); int howmany(); }; #endif
源文件
函数或类的实现代码放在源文件中。这样做的好处是,可以把头文件以源代码的方式提供给用户,而源文件则以编译后的目标文件的方式提供给用户,能够达到信息和技术保密的目的,也为多个程序员同时进行软件开发提供了技术支持。
例如:stack类的成员函数的实现放在同名的.cpp文件中。
//堆栈stack的源文件 stack.cpp
#include "stack.h" #include <iostream> using namespace std; Stack::Stack(int stacksize){ if(stacksize>0){ size=stacksize; data=new int[stacksize]; for(int i=0;i<size;i++) data[i]=0; } else{ data=0; size=0; } count=0; }
Stack::~Stack(){ delete []data; }
void Stack::Push(int x){ if(count<size){ data[count]=x; count++; } else cout<<"堆栈已满"<<endl; }
int Stack::Pop(){ if(count<=0){ cout<<"堆栈已空"<<endl; exit(1); } count--; return data[count]; }
int Stack::howmany(){ return count; }
main函数 对类的应用
//应用栈类的主程序:stackmain.cpp
#include "stack.h" #include <iostream> using namespace std; int main() { Stack s1; s1.Push(1); s1.Push(12); s1.Push(32); int x1=s1.Pop(); int x2=s1.Pop(); int c=s1.howmany(); int x3=s1.Pop(); cout<<"howmany:"<<c<<endl; cout<<x1<<"\t"<<x2<<"\t"<<x3<<endl; }
现在我们来研究如何把这三者合到一起,放到同一个项目中。
为了向用户隐藏实现代码,不把类的成员函数的代码暴露给用户,可以把类的实现文件编译成静态链接库(扩展名为.lib的文件),静态链接库由目标代码组成(即二进制代码文件),然后把它与类的头文件一起提供给用户。这样就避免了用户修改成员函数,实现了类接口与实现的分离。
首先,静态链接库的制作:
把stack.cpp制作成静态链接库stack.lib
1.建立目录,目的是为了了解此过程产生的临时文件,如:D:\cpp练习\3.14编程实做,并把stack.h和stack.cpp复制到此目录下。
2。启动vc++6.0,选择“文件。新建”,在工程标签项选择win32 static library,位置编辑处选择上一步新建的目录,工程名字填入:stack 如下图
3。把目录“D:\cpp练习\3.14编程实做”下的源文件stack.cpp添加到此工程中。

此时,工程目前只有一个源文件stack.cpp。
4。编译此工程。编译成功就会在目录“D:\cpp练习\3.14编程实做\stack\Debug”中形成stack.lib静态库文件。
然后是静态库的应用:
1 启动vc++6.0,建立一个简单的应用程序,程序代码如stackmain.cpp,然后把stack.h复制到该应用程序所在的磁盘目录中。
2 编译此程序会产生多个链接错误。
3 选择“工程-设置”,弹出的对话框选择“link”标签。在“L对象/库模块”下面的编辑框的最后输入stack.lib静态库文件所在的磁盘目录。如图:

编译程序,这次就不会有错了。
大功告成!!!
这种方法可以真正实现类的接口与实现的分离。类设计者将类的头文件与实现代码的静态库提供给用户,用户只能通过文件了解类的接口,以及类的成员函数的功能,但他们无法知道个成员函数的实现代码,也就无法修改成员函数的实现代码。
这就使类的封装和信息隐藏更加彻底。
不信,你可以打开stack.dsw文件,你是看不到里面的stack.app文件的内容的。
|