如何在 C++ 中编写类库,就像我们为函数编写的那样

kap*_*pil 2 c++ class static-libraries

假设我们需要编写一个我们打算在我们的程序中使用的函数库,那么我们可以通过以下方式编写它。

在 .h 文件中,我们声明函数(mylibrary 可以是我们希望的任何文件名)假设 sum 是我们希望在我们的库中拥有的函数

int sum(int x, int y);
Run Code Online (Sandbox Code Playgroud)

然后我们将有一个 .cpp 文件,它将定义如下函数:

#include "mylibrary.h"

int sum(int x, int y){ return x+y; }
Run Code Online (Sandbox Code Playgroud)

现在我们希望在我们的程序中使用这个函数,比如 myprog.cpp,我们可以这样使用:

#include
#include "mylibrary.h"

int main()
{
cout<<sum(10,20)<<endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,我们可以像对函数那样对类做类似的事情,即

我们可以在 .h 文件中声明类,例如:

class X;
class Y;
Run Code Online (Sandbox Code Playgroud)

然后在 .cpp 中定义类,如:

#include"myclasses.h"
class X
{
public:
int m;
};

class Y
{
public:
int n;
};
Run Code Online (Sandbox Code Playgroud)

然后在我们的程序中使用这些类,比如 myprog.cpp,像这样:

#include"myclasses.h"

int main()
{
class X myX;
myX.m = 0;
return 0;
}
Run Code Online (Sandbox Code Playgroud)

我试过了,得到了错误聚合“X myX”的类型不完整,无法定义。

如果我将整个定义放在 myclasses.h 文件中,那么它运行良好,没有错误。

zwo*_*wol 5

您可以将所有方法放在.cpp文件中,但必须在头文件中对进行“完整”声明。也就是说,你可以这样做:

// X.h
#ifndef _X_H
#define _X_H

class X {
    int data;
    void internal_method();

public:
    void foo();
    void bar();
};

#endif // X.h
Run Code Online (Sandbox Code Playgroud)

然后你可以在一个文件中定义X::foo, X::bar, and ,但你不能这样做或做任何类似的事情:X::internal_method.cpp

// X.h
#ifndef _X_H
#define _X_H

// This code is incorrect and will not even compile
class X;
public void X::foo();
public void X::bar();

#endif // X.h
Run Code Online (Sandbox Code Playgroud)

这是 C++ 的一个基本限制,是的,这意味着您不能在不重新编译所有内容的情况下更改数据成员或添加或删除方法 - 甚至是私有方法。该PIMPL黑客解决了这个问题,但有自己的问题。

(您可能已经注意到class X;all 本身一个有效的写法。这是类的“不完整”声明,它允许您声明涉及X 对象的指针引用的事物,但不包括 X 对象本身。例如,这个头文件有效的:

// Y.h
#ifndef _Y_H
#define _Y_H

class X;

class Y {
   X& ex;

public:
    Y(X& ex) : ex(ex) {}

    void foo();
    void bar(X& fx);
};

#endif // Y.h
Run Code Online (Sandbox Code Playgroud)

这可能是一件有用的事情,例如减少需要包含其他头文件的头文件的数量,并打破相互依赖循环(想象一下,如果class X有一些方法引用到 Y 参数,没有像这样的功能你根本写不出来)。)