C++ 静态库:从头文件隐藏私有成员

C++ 静态库:从头文件隐藏私有成员,c++,class,static-libraries,header-files,private-members,C++,Class,Static Libraries,Header Files,Private Members,我希望将我的部分代码编译为静态库,以包含在其他项目中。当然,我必须分发已编译的库和包含类声明和公共成员的头文件,但我不知道是否可以将所有私有成员和声明移动到与头文件不同的位置 例如: 在project.h文件中: class MyClass { public: MyClass(); void Give_me_an_input(int); int Get_your_output(); private: int a, b; int MySecretAlgorithm(); }

我希望将我的部分代码编译为静态库,以包含在其他项目中。当然,我必须分发已编译的库和包含类声明和公共成员的头文件,但我不知道是否可以将所有私有成员和声明移动到与头文件不同的位置

例如:

在project.h文件中:

class MyClass
{
public: 
  MyClass();
  void Give_me_an_input(int);
  int Get_your_output();

private:
  int a, b;
  int MySecretAlgorithm();
};
在.cpp文件中:

MyClass::MyClass()
{
  a = 1; 
  b = 0;
}

void MyClass::Give_me_an_input(int c)
{
  b = c;
}

int MyClass::Get_your_output()
{
  return MySecretAlgorithm();
}

int MyClass::MySecretAlgorithm()
{
  return (a + b);
}

是否有办法移动所有私有成员
inta,b
intmysecretalgorithm()到不同于头文件的地方?

多年来,我看到一些黑客这样做,但我认为它们不值得。如果你的库相当“笨重”(即:每微秒没有方法被调用十亿次);您可以重新编写代码块

您可以考虑将所有的公共数据都抽象为一个类(所有Virtual=0),然后从中派生出具体的类。 这方面的不足之处: -所有公共调用都变成虚拟的(一些优化可以绕过这一点,但并不经常)。 -你不能再“更新”你的类了,你需要实现一个工厂模式

我所熟悉的任何其他黑客的问题是,它们基本上在一组头中声明方法,然后在私有头中使用“真实”实现重新声明相同的内容-这取决于链接器匹配名称。这里有几个问题:

  • 维持这种混乱很糟糕。您不能使用#ifdef,因为它听起来像是要物理隐藏您的实现。因此,您有双重维护,或生成公共头的构建步骤

  • 只能通过指针使用。你必须玩一些游戏,使构造函数私有,并且仍然有一个工厂,因为如果你让客户端按值生成(或者甚至使用新的)编译器将不会生成正确大小的结构

  • 最后,我曾经看到一次黑客攻击,程序员试图在“public”类的私有区域声明一个字节数组,这样客户端代码仍然可以通过值或“new”来声明它。这会遇到前面所有的问题,而且您可能不想“知道”结构的大小,因为它们依赖于打包和对齐。您的“构建步骤”或多或少必须有一个使用sizeof()的运行时组件-现在如果要更改结构/类的大小,您就有一个版本控制问题


指向实现的指针习惯用法可以在这种场景中使用,通常称为。 基本思想是将实施细节从声明中删除 只需要一个指向实现细节的不透明指针

以下示例中使用了
std::unique_ptr
;但是你当然可以使用普通的指针

// my_class declaration unit.
class my_class {
private:
   class impl;
   unique_ptr<impl> pimpl;

public:

};

// my_class implementation unit
class my_class::impl {
   int whatever;
   int whenever;
};

my_class::my_class(): pimpl( new impl )
{
}
//my_类声明单元。
上我的课{
私人:
类impl;
独特的ptr pimpl;
公众:
};
//my_类实现单元
类my_类::impl{
int随便什么;
int,无论何时;
};
my_类::my_类():pimpl(新impl)
{
}

否,因为它们是类定义所必需的。但是您可以使用pimpl习惯用法(以间接方式为代价)重新实现该类。您是否关心其他人是否只能看到该声明?你可以用一个没有意义的假名字来声明它。然后,在
cpp
文件中实现它。在你的秘密文件中,创建一个指向这个函数的指针,如果有一个有意义的名字,如果你想从使用这个库的任何人隐藏信息,你可以考虑使用一些类似于<代码>矢量< /> >并根据需要铸造元素。不过,这也不太好。皮姆普尔的习语是+1,你为什么要这么做?动机/目标是什么?呃-我忘了这样做-这确实是最好的方法。但是,对于静态链接库来说,隐藏实现细节并没有任何意义,因为没有ABI问题,因此从中获得的好处很少甚至没有。