如何用 c++ 编写一个 class 库,就像我们为函数编写的库一样

How to write a class library in c++ like the one we write for functions

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

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

int sum(int x, int y);

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

#include "mylibrary.h"

int sum(int x, int y){ return x+y; }

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

#include
#include "mylibrary.h"

int main()
{
cout<<sum(10,20)<<endl;
return 0;
}

我的问题是,我们能否像对函数那样对 classes 做一些类似的事情,即

我们可以在 .h 文件中声明 classes 吗:

class X;
class Y;

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

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

class Y
{
public:
int n;
};

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

#include"myclasses.h"

int main()
{
class X myX;
myX.m = 0;
return 0;
}

我尝试了这个并得到错误聚合 'X myX' 类型不完整,无法定义。

如果我将整个定义放在 myclasses.h 文件中,那么它可以正常运行而不会出错。

您可以将所有 方法 放入 .cpp 文件中,但您必须有 的 "complete" 声明class 在头文件中。也就是说,你可以这样做:

// X.h
#ifndef _X_H
#define _X_H

class X {
    int data;
    void internal_method();

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

#endif // X.h

然后您可以在 .cpp 文件中定义 X::fooX::barX::internal_method,但您不能这样做或类似的事情:

// 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

这是 C++ 的基本限制,是的,这意味着您不能更改数据成员或添加或删除方法 - 甚至是私有方法 - 如果不重新编译所有内容。 pimpl hack 可以解决这个问题,但也有其自身的问题。

(您可能已经注意到 class X; 本身 一个有效的写法。那是 class 的 "incomplete" 声明=],它允许您声明涉及 X 对象的 pointersreferences 的东西,但不是 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

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

是的,你可以做到; 但是 class 的完整声明——类似于声明一个函数——涉及声明它的所有成员。 (有关详细信息,请参阅 http://en.cppreference.com/w/cpp/language/class,但我认为您已经熟悉它们。)

如果你简单地 "forward declare" class,通过写 class Foo; 而没有完全声明它,那么你仍然可以传递指向它的指针,但你不能引用任何它的成员,包括它的构造函数(甚至是编译器生成的,因为它们不是 无条件地 生成的;并非所有 class 都有它们)。请注意,前向声明甚至不足以告诉编译器实例有多大 (sizeof).