我正在阅读Paul Deitel的“如何编程”一书。按照他的说法,我们可以创建一个不包含成员函数详细信息的文件。
“为了隐藏类的成员函数实现细节,类实现程序员将为客户端代码程序员提供标题Time.h(它指定类的接口和数据成员)和Time对象代码(即,表示Time的成员函数的机器代码指令。客户端代码程序员没有给出Time.cpp,因此客户端仍然不知道Time的成员函数是如何实现的。“
我在dev中开发了以下简单的代码来测试这个概念,但是在编译哪个文件等同于cpp文件后我不知道。
区域类别:
#include<iostream>
using namespace std;
class Area {
public:
int square(int);
private:
int x;
};
包含成员函数功能的源代码Area.cpp
#include<iostream>
#ifndef AREA_HH
#define AREA_HH
# include "Area.h"
int Area::square(int x)
{
return x*x;
}
#endif
主:
#include<iostream>
#include "Area.h"
using namespace std;
int main ()
{
Area Obj1;
cout<<Obj1.square(4);
return 0;
}
Dev创建的文件有:Area.cpp,Area.o,Area.h,main.cpp,main.o,Makefile.win,layout和exe。
答案 0 :(得分:1)
编译后哪个文件等同于cpp文件我不知道。
这是实现.h文件中声明的函数的文件。在您的情况下,它是“Area.cpp”。
答案 1 :(得分:1)
您无法将类与可执行文件隔离开来。要共享这样的功能,您必须构建库而不是应用程序。要了解为什么在构建项目时找不到包含课程的单个自包含文件,您必须了解构建的工作原理。
C ++应用程序的标准结构看到功能在翻译单元(.cpp文件)之间分开。这些文件包含函数的定义。为了从其他翻译单元使用这些功能,功能声明需要对这些单元可见。因为我们不希望include
我们需要的每个.cpp文件的全部内容,所以我们通常将声明分隔为头文件(.h或.hpp)。例如:
Circle.h:
// This is where you would put an include guard (NOT IN THE CPP FILE)
struct Circle {
// Note that member variables need to be visible in the header
float radius;
float area();
}
Circle.cpp
float Circle::area() {
return 2.0 * PI * radius;
}
的main.cpp
#include "Circle.h"
int main() {
Circle c;
c.radius = 5.0;
float area = c.area();
}
构建项目时,编译器将为每个翻译单元输出一个目标文件,例如Circle.o和main.o.因为编译器一次只能在一个翻译单元(cpp)上工作,所以它们不是自包含的。例如,在main.o中有一个尚未解析的c.area()
引用。因为函数的签名是通过包含的.h文件提供的,所以编译器知道如何调用它而不是如何找到它。链接器将获取所有目标文件并将它们链接到单个可执行文件中,例如MyProject.exe。
因此,在标准C ++应用程序中,没有“等同于cpp文件”。中间.o不打算共享并包含在其他项目中,MyProject.exe只是一个可执行文件。
您实际需要做的是建立一个库。这是一种不是独立应用程序的可执行文件。然后链接器的最终输出将是.dll,.lib,.so或.a(取决于链接的平台和方法),它将以可执行(非源代码)形式保存所有函数实现。然后,您可以将库与.h文件一起分发,并让人们链接到该文件。
同样,没有“等效的cpp”文件。构建的库将包含您指定为输入的所有翻译单元,因为构建过程与上面的非常相似。区别在于输出不是可执行应用程序,而是一个库,根据需要从另一个链接到该库的应用程序中调用函数。
没有统一的方法来构建库。当您使用IDE时,它可能是创建新项目时的一个选项。
答案 2 :(得分:0)
实现源代码为Area.cpp
,并将其编译为文件Area.o
中的实现对象代码。
如果您要分发您的区域库,您可以创建一个库(Area.a
,Area.so
,Area.dll
或Area.lib
,具体取决于平台和链接式选择),并与Area.h
一起分发。
一般规则是将任何源文件%.cpp
编译为目标文件%.o
。
请注意,您已完全清楚Area.h
和Area.cpp
是输入到编译器(因为您自己编写),文件时间戳将显示哪个您列出的文件是由编译器创建的,并且您有一个Makefile,它指定完全哪个文件是从哪个源构建的,或者描述了与输入和输出文件名相关的模式......