How to hide functions and classes form the end user of a C++ API

Started by
3 comments, last by the_edd 13 years, 6 months ago
My game engine consists mainly of classes and the classes have to communicate information with each other through class variables and functions but I don't want to allow the user of my API to access these variables or functions because if written to they will cause the engine to crash and I also want to make it clear just from including the header which function the user should use.

Specifying private inside a class allows only the things within a class to access those variables and functions but how can I make it so that only things within my API can access the variables and functions?

EDIT: Now that I actually wrote out the problem and had more time to think about it I think all I am suppose to do is remove those variables and functions from the header file that the user includes into their project but I'm wondering if that means I have to make a user and a compiler version of each header?
Advertisement
How are you delivering the API to your users?
If it's in the form of a lib then don't give them the headers needed to access the parts that you don't want your users to access. If it's in the form of a dll do the same, and additionally don't export the symbols.
The “simplest” and most straight forward way I can think of, is to wrap stuff you don't want exposed into a separate library (a dynamically linked library usually) and then use interfaces to expose the functionality you want to your end users.

The private / protected keywords in C++ is actually a measure of syntactic encapsulation: Encapsulation that's enforced by the complier during compile time.

In your case (I think), what you need is binary encapsulation: Wrapping up whatever code you deem "private" in a separate module, which you then allow others to link to.

The beauty of code like this, is that you can even change the module at will, without effecting your user base, so long as the basic interface remains constant.

Simple strategy yes but, as they say, the devil is very much in the details. But yeah, I think the solution to your problem is binary encapsulation.
The preferable way is to provide a header file or exported interface with only the things they should use, and document the methods that they are supposed to use. You can't necessarily prevent people from doing stupid things with your engine, so you shouldn't expend too much effort trying to prevent them.
Quote:Original post by SteveDeFacto
Specifying private inside a class allows only the things within a class to access those variables and functions

Right.

Quote:but how can I make it so that only things within my API can access the variables and functions?


It depends what you mean by access.

If you want to prevent clients of your library from even being able to guess about the implementation, you can use the "pimpl idiom" in your classes. The idiom also has some other benefits, such as reducing header dependencies, though this comes at the expense of a little more maintenance. However, using the pimpl idiom purely because you don't want people to see your private declarations is a bit silly, IMVHO.

If you just want to stop clients from modifying the members of your classes, private is entirely sufficient. You can have your class declare friends (I'm assuming you're using C++ here) so that other parts of your library can access your objects' members, even though external clients of your library can't. However, too many friendships could point to a poor design.

Also, it's perfectly fine (in my book at least) to document those parts that necessarily leak in to the client domain as implementation details; "don't rely on this, it may be removed or changed in future", or something like that. If the client does start relying on it, that's their own fault.

Quote:EDIT: Now that I actually wrote out the problem and had more time to think about it I think all I am suppose to do is remove those variables and functions from the header file that the user includes into their project but I'm wondering if that means I have to make a user and a compiler version of each header?


You only need to expose to the client what the compiler needs to compile client code. In many cases you can get away with forward declarations. Further practice with the language will help you get an idea of what can be forward declared and how you'd go about it. One of Herb Sutter's Exceptional C++ books has a couple of good sections on forward declarations and pimpl-ing.

But it is indeed common to have "internal" headers that are only included by those source files that form the implementation of your library. You library sources can include both public and internal headers, but only the public headers are advertised to clients. You don't need to have two sets which repeat a subset of your declarations (that's dangerous, in fact). I'd say that putting public headers in a separate directory is a good idea.

This topic is closed to new replies.

Advertisement