Hiding private members of c++ library

You can create a publicly-visible interface. Create an abstract class with the functions you want to expose, then have your implementation extend it.

For example, an interface:

class Interface {
public:
    virtual void publicMethod() = 0;
...
};

And the implementation:

class Implementation : Interface {
public:
    virtual void publicMethod();
private:
    int hiddenMethod();
};

Then you only export the symbols for Interface. Now, in order for the user of the library to get instances of Interface which are actually Implementations, you need to provide a factory:

class Factory {
public:
    //can create and return an Implementation pointer, but caller will get an Interface pointer
    std::shared_ptr<Interface> getImplementationInstance();
}

In addition to the Factory pattern (which, in my opinion, can become unwieldy), you can also hide your private members behind a PIMPL (Pointer to IMPLementation):

// Interface.hpp
class Implementation;
class Interface {
public:
    Interface() : pimpl(new Implementation()) {}
    void publicMethod();
private:
    std::unique_ptr<Implementation> pimpl;
};

// Interface.cpp
class Implementation {
public:
    void PrivateMember();
};

void Interface::publicMethod() { pimpl->PrivateMember(); }

This has the advantage of hiding implementation, at the cost of a single pointer indirection, not much different from the typical inheritance-based Factory pattern.

This can also be ABI stable. Changes to your implementation won't affect linkage, since no changes will ever be visible to the rest of the program. This is a good pattern to use when implementing shared objects, for example.

It's also a common C++ idiom, so other C++ programmers will recognize it without question.

In the case of a class which will follow the Singleton pattern, you can avoid exposing the PIMPL at all, and simply write the entire implementation in an anonymous namespace in your .cpp file, where you can put as much state and private functions as you wish, without even hinting at it in your interface.