我试图使用模板来实现这一点,但它不起作用。我在内部头文件test_inner.hpp
:中定义了一个Incomplete
模板类
#define VISIBLE __attribute__((visibility("default")))
typedef int Dummy;
template <typename T> class Incomplete
{
};
在src文件中,我专门化了Incomplete<Dummy>
:
#include "test_inner.hpp"
template <> class VISIBLE Incomplete<Dummy>
{
private:
int a = 3;
public:
int f()
{
std::cout << "a: " << a << std::endl;
return 0;
}
};
template class Incomplete<Dummy>;
extern "C" VISIBLE
void test(Incomplete<Dummy> *a)
{
a->f();
}
在外部头文件中,只需声明Incomplete
:的显式实例
#include "test_inner.hpp"
extern template class VISIBLE Incomplete<Dummy>;
extern "C" VISIBLE void test(Incomplete<Dummy> *a);
上面的代码将被构建到一个共享库中,下面是我的测试代码:
#include "test.hpp"
test(new Incomplete<Dummy>);
代码工作不正常,可能是因为它实例化的实例与共享库中的实例完全不同。
在我的例子中,我不想公开任何实现,但用户仍然可以从类继承并将派生类注册到库中。
new
需要完整的类型。
所以你可以使用你的不透明类型创建工厂和免费功能,比如
// Header:
class MyHandle;
std::shared_ptr<MyHandle> CreateMyHandle(/*..*/);
void doJob(MyHandle&);
并且cpp文件包含上述的定义。
用途与类似
auto handle = CreateMyHandle();
doJob(*handle);