如何在共享类时隐藏成员函数文件

时间:2018-03-26 16:24:43

标签: c++ c++11 c++14

我正在阅读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。

3 个答案:

答案 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.aArea.soArea.dllArea.lib,具体取决于平台和链接式选择),并与Area.h一起分发。

一般规则是将任何源文件%.cpp编译为目标文件%.o

请注意,您已完全清楚Area.hArea.cpp输入到编译器(因为您自己编写),文件时间戳将显示哪个您列出的文件是由编译器创建的,并且您有一个Makefile,它指定完全哪个文件是从哪个源构建的,或者描述了与输入和输出文件名相关的模式......