0

I try to use template to achieve this, but it doesn't work. I define an Incomplete template class in the internal header file test_inner.hpp:

#define VISIBLE __attribute__((visibility("default")))
typedef int Dummy;
template <typename T> class Incomplete
{
};

And in the src file, I specialized the 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();
}

In the external header file, just declare the explicit instance of Incomplete:

#include "test_inner.hpp"

extern template class VISIBLE Incomplete<Dummy>;

extern "C" VISIBLE void test(Incomplete<Dummy> *a);

The above code will be built into a shared library, and the following is my test code:

#include "test.hpp"
test(new Incomplete<Dummy>);

The code is not working correctly, possibly due to it instantiates a totally different instance compared with the instance in the shared library.

In my case, I don't want to expose anything of the implementation, but the user is still able to inherit from the class and register the derived class to the library.

Alex
  • 44
  • 5
  • Hiding the implementation of a class is often done via [PIMPL](https://stackoverflow.com/questions/60570/why-should-the-pimpl-idiom-be-used) – Cory Kramer Jun 28 '21 at 14:03
  • @CoryKramer But PIMPL doesn't hide member function names – Alex Jun 28 '21 at 14:04
  • You can use opaque pointers in your public interface headers to hide implementation. (This is the technique used a lot by Apple in their headers.) You'll need thunk functions for the opaque pointer in your public interface header. – Eljay Jun 28 '21 at 14:05

1 Answers1

0

new requires complete type.

So you might create factory, and free function using your opaque type, something along:

// Header:
class MyHandle;
std::shared_ptr<MyHandle> CreateMyHandle(/*..*/);
void doJob(MyHandle&);

and cpp file contains definitions of the above.

Usage would be similar to

auto handle = CreateMyHandle();
doJob(*handle);
Jarod42
  • 203,559
  • 14
  • 181
  • 302