如何重用其他项目中的源代码

来源:互联网 发布:怎样下载photoshop软件 编辑:程序博客网 时间:2024/06/04 08:18

做软件,都希望能够重用已经存在的代码,而重用方式大概有以下两种吧:1. 以代码的形式复用,也就是直接复制源代码,这可能是最原始的了吧;2. 以类的形式复用,也就是平常所说的继承和组合了。而今天,我想说说这第二种代码复用的方式。

如果是在一个项目中,这没什么好说的,因为同在一个项目中,各个类之间彼此都可访问——大不了就是加个include而已吗。而如果是想复用其他项目中的类呢?先看一个例子吧(本文环境为Visual C++ 2005):

创建一个空的控制台项目MyClass,并加入两个文件(其实就是类Hi的声明和实现文件):

Hi.h文件:

#pragma once

class Hi{
public:
    
void hi();
}
;

 

Hi.cpp文件:

#include "Hi.h"
#include 
<iostream>
using namespace std;

void Hi::hi(){
    cout
<<"Hi!"<<endl;
}

 

为了验证这个类可以正常运行,再添加一个Run.cpp文件:

#include "Hi.h"
#include 
<iostream>
using namespace std;

int main(){
    Hi hi;
    hi.hi();

    cin.
get();
}

 

运行,可以看到程序向控制台输出了 Hi! ,说明类Hi是没有任何问题的。

 

好,那就可以进行下一步了。现在,我想在另外一个项目中使用类Hi。很简单,创建了一个空的控制台项目Reuse,添加了文件UseHi.cpp,如下:

#include "Hi.h"
#include 
<iostream>
using namespace std;

int main(){
    Hi hi;
    hi.hi();

    cin.
get();
}

 

大家可以看到,这和MyClass项目中的Run.cpp文件是一模一样的。其实也应该这样,它们不都是导入"Hi.h"文件,然后再执行Hi.hi()函数吗?不过……按F5运行,竟然编译出错,提示如下:

----- 已启动生成: 项目: Reuse, 配置: Debug Win32 ------
正在编译...
UseHi.cpp
d:/cpp/myobjects/reuse/usehi.cpp(1) : fatal error C1083: 无法打开包括文件:“Hi.h”: No such file or directory
生成日志保存在“file://d:/Cpp/MyObjects/Reuse/Debug/BuildLog.htm”
Reuse - 1 个错误,0 个警告
========== 生成: 0 已成功, 1 已失败, 0 最新, 0 已跳过 ==========

看来是找不到Hi.h文件。不过也是,include只能是在当前目录和系统指定目录下查找头文件,而我们所要导入的Hi.h文件是在我们自己建立的文件夹中,按理说也找不到它。不过这个倒也好解决:依次点击“项目——ReUse 属性——配置属性——C/C++——常规”,在“附加包含目录”中加入Hi.h所在的文件夹,本例中为D:/Cpp/MyObjects/MyClass。确定,编译运行。——没有了刚才的错误提示,不过,呵呵~

------ 已启动生成: 项目: Reuse, 配置: Debug Win32 ------
正在编译...
UseHi.cpp
正在编译资源清单...
正在链接...
UseHi.obj : error LNK2019: 无法解析的外部符号 "public: void __thiscall Hi::hi(void)" (?hi@Hi@@QAEXXZZ),该符号在函数 _main 中被引用
D:/Cpp/MyObjects/Reuse/Debug/Reuse.exe : fatal error LNK1120: 1 个无法解析的外部命令
生成日志保存在“file://d:/Cpp/MyObjects/Reuse/Debug/BuildLog.htm”
Reuse - 2 个错误,0 个警告
========== 生成: 0 已成功, 1 已失败, 0 最新, 0 已跳过 ==========

竟然又出现了其他的错误……

而这个错误,当时我是拿它一点办法都没有,只能是郁闷的避开它。后来不断的在网上查找,才稍微看到了点解决的眉目。现在先把解决办法写下来,再谈谈我的感受吧。

打开MyClass项目,依次点击“项目——MyClass 属性——配置属性——常规”,将“配置类型”更改为“静态库(.lib)”,然后F7(生成解决方案),以创建文件MyClass.lib。再回到ReUse项目,依次点击“项目——ReUse 属性——配置属性——链接器——常规”,在“附加库目录”中加入MyClass.lib所在目录,本例中为D:/Cpp/MyObjects/MyClass/Debug。还没完,在“链接器”中找到“输入”,在“附加依赖项”中加入MyClass.lib,确定,F5,结果……呵呵,成功!

 

分析:

文件UseHi.cpp中的 #include "Hi.h" ,只是导入了头文件Hi.h中的内容,也就是导入了类Hi的声明。而在项目ReUse中不可能再去到MyClass项目所在文件夹中去寻找类Hi的实现文件,所以才会弹出错误提示“无法解析的外部符号/命令”。而在MyClass中Run.cpp可以正常运行的原因在于:它导入了类Hi的声明后,会从当前目录中查找看有没有类Hi的实现,而Hi.cpp就是在MyClass项目中,所以才能够正常将声明与实现相链接。

所以,按这样说来,如果在项目ReUse中加入类Hi.h的实现后,即便是不更该项目ReUse的链接器中的默认选项,还是可以正常运行的,呵呵,那就尝试一下吧。将之前更改的项目ReUse中链接器中的选项都改回默认值,再向项目ReUse中添加文件Implement.cpp文件。其中Implement.cpp文件文件如下(其实就和Hi.cpp一模一样):

#include "Hi.h"
#include 
<iostream>
using namespace std;

void Hi::hi(){
    cout
<<"Hi!"<<endl;
}

 

F5,呵呵,真的是这样,可以正常运行了。

所以,可以这么说:如果是include了某个头文件,那么它会在当前目录中去找其实现文件,如果找不到,就只有是“无法解析的外部符号/命令”了,而不会再去别的文件夹中去搜索其实现文件了。而如果我们是用的.lib库的方式复用的代码,那么我们就需要将该.lib库的路径加入到在“链接器”的“附加库目录”中,并将该库的名称加入到“链接器”的“附加依赖项”中。这样,当我们导入了某个头文件时,就可以去该.lib库中去查找其实现文件了。

 

呵呵,终于完了,睡觉去~

原创粉丝点击