我将此代码用于头文件中的类的接口,并将其实现在单独的源文件中:
首先:头文件“Gradebook.h”
#include <string>
using namespace std;
class Gradebook{
public:
Gradebook(string);
void setCoursename(string);
string getCoursename();
void displayMessage();
private:
string nameofCourse;
};
第二:实施“Gradebook.cpp”
#include "stdafx.h"
#include "Gradebook.h"
#include <iostream>
using namespace std;
Gradebook::Gradebook(string name){
setCoursename(name);
}
void Gradebook::setCoursename(string name){
nameofCourse = name;
}
string Gradebook::getCoursename(){
return nameofCourse;
}
void Gradebook::displayMessage(){
cout << "Display message function shows :" << getCoursename() << endl;
}
我如何链接这两个单独的文件,以便在其他项目中只使用“Gradebook.h”,并从客户端程序员隐藏我的实现?
答案 0 :(得分:2)
有几个答案。这有助于了解您实际上想要隐藏实现的原因。以下是您可能想要这样做的原因,我可以随意思考。
保护商业机密:忘掉它吧。为了能够执行您的代码,计算机必须能够运行它。实际上,您可以通过将代码编译为静态库来删除注释,方法名称和变量名称,甚至在其上运行混淆器来模糊控制流(以增加不必要的跳转来降低速度为代价),但最终代码(或从中生成的机器代码)具有以保持可读性或无法执行。
让代码更容易使用:如果您有多个源文件并且可能会添加更多文件,并且您希望您的客户能够放入一个文件来获取所有文件最新的更改,无需添加单个源文件,将其编译为静态或动态库。然后你可以把图书馆和标题交给某人,他们就可以使用它们了。
您还可以创建一个&#34;伞形标题&#34;包括所有其他标头。这样,客户端可以简单地将库includes
文件夹的路径添加到其编译器调用/项目文件中,并包含一个标头,其中包含所有其他标头。如果添加或拆分标题,只需更改标题以包含新标题,并使用它的所有项目继续工作。
请注意,使用库会限制您的客户:他们无法轻松地在调试器中逐步执行您的代码,他们无法轻松修复和编译内容。如果他们需要您的代码在新平台上运行,或者想在编译器中使用不同的优化设置,他们就不能重新编译它。
另一方面,如果您打算出售图书馆,您可能希望保留自己的资源。如果您停业,不关心代码安全性的客户可以在没有源代码的情况下获得更便宜的库版本,如果他们想要通过制作任何其他功能,您可以额外收费他们为你为他们编码的新平台购买了一个版本,等等。
防止客户意外地依赖实施细节:除非将代码拆分为公共和私有文件,否则您不需要为此做任何事情。通常你的实现文件是私有的,你的标题是公共的,但你可能有一些内部类的私有标题。
由于C ++不允许定义实例变量或方法,这些变量或方法不像其他语言那样在标题的类声明中声明,它支持 categories 或 class extensions < / em>,您可能不得不求助于私人实施(又名&#39; pimpl&#39;)模式。
这通常意味着您声明一个定义公共API的类,该类简单地将指针包装到包含实际实现的实际类并调用它。它通常只有一个实例变量pimpl
,它是指向另一个类的指针。您只需使用class Foo;
转发声明私有类,从而使您的客户&#39;代码对私有类一无所知(除非他们明确查看实现文件或私有标题,例如在修复错误时)。
创建单个文件类我最后提到这个,因为它通常是一个愚蠢的事情,但理论上,你也可以移动实现文件的内容进入标题。然后客户端只需要包含标头并获取所有源。但是,这有很多缺点,比如使代码更难以阅读,减慢编译时间,并要求客户端处理由于包含来自多个.cpp
文件的文件而导致的类的重复定义。简而言之:不要这样做。