What is best practice for C++ Public API? - c++

What is best practice for C++ Public API?
I am working on a C++ project that has multiple namespaces, each with multiple objects. Some objects have the same names, but are in different namespaces. Currently, each object has its own .cpp file and .h file. I am not sure how to word this... Would it be appropriate to create a second .h file to expose only the public API? Should their be a .h file per namespace or per object or some other scope? What might be a best practice for creating Public APIs for C++ libraries?
Thanks For Any Help,
Chenz

It is sometimes convenient to have a single class in every .cpp and .h pair of files and to have the namespace hierarchy as the directory hierarchy.
For instance if you have this class:
namespace stuff {
namespace important {
class SecretPassword
{
...
};
}
}
then it will be in two files:
/stuff/important/SecretPassword.cpp
/stuff/important/SecretPassword.h
another possible layout might be:
/src/stuff/important/SecretPassword.cpp
/include/stuff/important/SecretPassword.h

G'day,
One suggestion is to take a look at the C++ idiom of Handle-Body, sometimes known as Cheshire Cat. Here's James Coplien's original paper containing the idiom.
This is a well known method for decoupling public API's from implementations.
HTH

I'd say it's best decided by you, and the type of 'library' this is.
Is your API provides one "Action"? or handles only one abstract "Data type"? examples for this would be zlib and libpng. Both have only one header that gives everything that is needed to perform what the libraries are for.
If your library is a collection of unrelated (or even related) classes that do, or not, the same goal, then provide each subset with it's own header. Major example for this will be boost.

Here is what I'm used to do:
"Some objects have the same names, but are in different namespaces"
That's why namespaces exist.
"Would it be appropriate to create a second .h file to expose only the public API? "
You always should expose only the public API. But what means to expose public API? If it would be only to headers then, since public API relies on private API, the private API would be included by public API anyway. To expose a public API mark public functions/classes with a macro (which in case of Windows exports public functions to the symbol table; and probably it will be soon adopted by Unix systems). So you should define a macro like MYLIB_API or MYLIB_DECLSPEC, just check some existing libraries and MS declspec documentation. It is sufficient, usually non-public API will be kept in subdirectories so it doesn't attend library's user.
"Should their be a .h file per namespace or per object or some other scope?"
I prefer Java-style, one public class per header. I found that libs written in this way are far more clean and readable than those which are mixing file and structure names. But there are cases when I brake this rule, especially when it comes to templates. In such cases I give #warning message to not include header directly and carefully explain in comments what is going on.

Great response LiraNuna.
Are you providing an API to an application or a library?
An application API will generally only provide methods that either query the state of an application or attempt to alter that state. In this case you'd generally have separate interface declarations in a separate header file. Your objects would then implement this interface to handle API requests.
A library will generally expose objects that can be re-used. In this case, generally speaking, your API is simply the public methods in the header file.

I agree with what doc said - one class per file. 99.9% of the time!
Also, consider what filenames to use. It's generally a bad idea to have multiple headers of the same name in different directories, even though the classes they contain may well be in different namespaces.
Especially if this is a public API, you probably cannot control what include paths are defined by the user of your library, so a build may find the wrong one. Tweaking the order of include paths would definitely not be a solution I'd recommend!
We use a naming convention of Namespace-Class.h to explicitly identify classes in files.

Related

class library and pimpl - splitting class accessibility

I want to make a class-library using pimpl idiom, so that I can hide my implementation details for the user of the library.
Is it possible, to make a class, where some methods are public and callable from users perspective, while having methods that are only callable from the internals.
Right now I only see a solution with the friend keyword and declaring the internal methods private.
For example:
MyPartiallyVisibleClass: Class containing a mixture of methods accessible to the user, and methods only accessible to the internals of library.
InternalClass: Class internally in the library. The user will never know this excist.
// MyPartiallyVisibleClass.h: Will be included by the user.
class MyPartiallyVisibleClass
{
private:
class Impl; // Forward declare the implementation
Impl* pimpl;
InternalMethod(); // Can only be called from within the library-internals.
public:
UserMethod(); // Will be visible and callable from users perspective.
}
// MyPartiallyVisibleClass.cpp
class MyPartiallyVisibleClass::Impl
{
private:
InternalMethod();
public:
UserMethod();
friend class InternalClass;
}
// Internal class that will not be included into users application.
class InternalClass
{
public:
InternalMethod()
{
MyPartiallyVisibleClass pvc;
pvc.InternalMethod();
}
}
Is there a better way of doing this?
There are pros and cons.
By a source stand point, if you distribute only headers and binaries, everything in in cpp files will not be seen by the source user.
So, also MyPartiallyVisibleClass::Impl::Usermethod is not visible, but being public, callable everywhere in the cpp file it is declared.
Zero way, one way or two way friendship between external and internal class can be required if you don't want to repeat external methods internally. It can seem an encapsulation break, but it is not, since the "capsule" here, is the external class. Creating complex hierarchy of intenal privacy (public external, private external, public internal private internal public even more internal ... etc.) can become clueless if everything goes under your same responsibility. Unless the internal part is so large to be assigned to different developers, so that another level of interface & implementation is needed.
By a binary user standpoint, however, every function that is not inlined exist, and -having external linkage- its name is available into the library, and hence it is "callable" by writing another header that makes it publicly available to other sources. I will just be an undocumented feature.
The concept of public/private etc. is for code safety (avoid function you don't want to promise to maintain with always the same "contract" to be available, thus making external code more stable, eliminating unwanted dependency) not for "security" (avoid who wants to call to find a way to call).
There is then also another drawback: templates cannot be hidden into sources, since they have to be expanded into the users's source code space (not the developer binary space). And the growing of generic programming, functional static polimorphism etc. makes the pimpl idiom less and less attractive.
There are today many programs made by a single cpp file that instantiate a single "manager object" whose entire functionality reside as is made of header only libraries. Believing or not, this way to program makes code even more portable between compilers, since it doesn't have to exist in a different binary form for every possible client compiler. And does not necessarily make build time longer: precompiled header can be generated once for code that don't change too often. Who cares is the user ca see the code? If he wants to use it and be supported is not his interest to change it improperly. If he wants to hack or stole, he will find anyway another way to do it.

Using third party classes in a C++ header file

Suppose there's a third party class named (including namespace) other::OtherClass.
And this is the header file.
class MyClass {
public:
...
private:
other::OtherClass other_class_;
...
}
If this header file was shipped in production, would this be considered exposing the implementation to the client?
On the other hand, is it a good idea or not to use a third party class in a public interface? (Note that this second example doesn't necessarily save that class into a private member.)
class MyClass {
public:
MyClass(const other::OtherClass& other_class);
...
private:
...
}
In the first example, the client has to know the size of other::OtherClass and include the header file. In the second example, the client needs to be able to construct other::OtherClass which also might need the header file if a factory was not provided.
Are there good excuses in doing any of the examples above?
If this is almost never a good idea, what is the usual way to design classes like above?
Vendors have to expose some amount of their library to clients through the header files they provide.
That being said, there are techniques for hiding data and functions within an implementation. One of the more common techniques is to provide public proxy classes and factory functions, which expose only a mimimal amount of public functionality to clients.
As to your second question, it's better to use references and pointers to the third-party types in your headers, since you can forward-declare the types within your header file as:
class other::OtherClass;
within needing to actually include the third-party header files. This does not expose any of the third-party details to clients of your libraries.
With a public header interface, you should be making least amount of commitment and exposing least amount of details as possible. Everything else should be implementation detail.
I can't see any justification for tight coupling your interface with 3rd party class, even if you are not looking at being able to replace the vendor in future.
There are way many things to be considered in designing an interface/impl. You could refer to a design patterns book

c++ interface question

I have
Package A (Namespace A), which has header file say internalItems.hpp, contains a class with enumeration of items to be created and methods to get and set item type.
Now this class has to be made available in common package (Package Common with Namespace COMMON) so that other package (let says Package EndUser with Namespace EUSER) can use enumeration type.
What is the best way to do it ?
Thanks you for your valuable responses.
I think you're asking how to expose the classes and enums in internalitems.hpp to your EUSER project from your Common library.
You're going to have to #include "internalitems.hpp" in any file that needs to use the enums or classes defined in it, no matter which project they're in. In that case if internalitems is intended to be an internal, not-exposed-to-library-consumers header file then you'll need to promote so it is part of the Common library interface headers or at least filter out the parts that the external code needs to use into a public header file.

How to better organize the code in C++ projects

I'm currently in the process of trying to organize my code in better way.
To do that I used namespaces, grouping classes by components, each having a defined role and a few interfaces (actually Abstract classes).
I found it to be pretty good, especially when I had to rewrite an entire component and I did with almost no impact on the others. (I believe it would have been a lot more difficult with a bunch of mixed-up classes and methods)
Yet I'm not 100% happy with it. Especially I'd like to do a better separation between interfaces, the public face of the components, and their implementations in behind.
I think the 'interface' of the component itself should be clearer, I mean a new comer should understand easily what interfaces he must implement, what interfaces he can use and what's part of the implementation.
Soon I'll start a bigger project involving up to 5 devs, and I'd like to be clear in my mind on that point.
So what about you? how do you do it? how do you organize your code?
Especially I'd like to do a better
separation between interfaces, the
public face of the components, and
their implementations in behind.
I think what you're looking for is the Facade pattern:
A facade is an object that provides a simplified interface to a larger body of code, such as a class library. -- Wikipedia
You may also want to look at the Mediator and Builder patterns if you have complex interactions in your classes.
The Pimpl idiom (aka compiler firewall) is also useful for hiding implementation details and reducing build times. I prefer to use Pimpl over interface classes + factories when I don't need polymorphism. Be careful not to over-use it though. Don't use Pimpl for lightweight types that are normally allocated on the stack (like a 3D point or complex number). Use it for the bigger, longer-lived classes that have dependencies on other classes/libraries that you'd wish to hide from the user.
In large-scale projects, it's important to not use an #include directives in a header file when a simple forward declaration will do. Only put an #include directives in a header file if absolutely necessary (prefer to put #includes in the implementation files). If done right, proper #include discipline will reduce your compile times significantly. The Pimpl idiom can help to move #includes from header files to their corresponding implementation files.
A coherent collection of classes / functions can be grouped together in it's own namespace and put in a subdirectory of your source tree (the subdirectory should have the same name as the library namespace). You can then create a static library subproject/makefile for that package and link it with your main application. This is what I'd consider a "package" in UML jargon. In an ideal package, classes are closely related to each other, but loosely related with classes outside the package. It is helpful to draw dependency diagrams of your packages to make sure there are no cyclical dependencies.
There are two common approaches:
If, apart from the public interface, you only need some helper functions, just put them in an unnamed namespace in the implementation file:
// header:
class MyClass {
// interface etc.
};
// source file:
namespace {
void someHelper() {}
}
// ... MyClass implementation
If you find yourself wanting to hide member functions, consider using the PIMPL idiom:
class MyClassImpl; // forward declaration
class MyClass {
public:
// public interface
private:
MyClassImpl* pimpl;
};
MyClassImpl implements the functionality, while MyClass forwards calls to the public interface to the private implementation.
You might find some of the suggestions in Large Scale C++ Software Design useful. It's a bit dated (published in 1996) but still valuable, with pointers on structuring code to minimize the "recompiling the world when a single header file changes" problem.
Herb Sutter's article on "What's In a Class? - The Interface Principle" presents some ideas that many don't seem to think of when designing interfaces. It's a bit dated (1998) but there's some useful stuff in there, nonetheless.
First declare you variables you may use them in one string declaration also like so.
char Name[100],Name2[100],Name3[100];
using namespace std;
int main(){
}
and if you have a long peice of code that could be used out of the program make it a new function.
likeso.
void Return(char Word[100]){
cout<<Word;
cin.ignore();
}
int main(){
Return("Hello");
}
And I suggest any outside functions and declarations you put into a header file and link it
likeso
Dev-C++ #include "Resource.h"

DLL library interface

I have a question that bothers me for a long time.
I have a mathematical library, implemented as DLL.
The library implements many types of mathematical functions.
The mathematical functions are implemented in different classes based on their functionality. For example, all functions that implements polynomial equations are under CPolynom, all functions that implements differential equations are under CDifferential.
The DLL has to expose an interface.
Now my question:
Option 1
I can implement in one header file, one interface class which includes all the “sub” interface methods of all practical classes => On one hand, I expose to the outside world only one header file with one class, on the other hand this class might be huge, including interface methods which are not related (i.e. someone wants the CPolynom functionality, he/she will have to include huge header file and construct huge interface class)
Option 2
I can implement interface class for each class in different header file.
=> On one hand I split classes to different files based on functionality. If someone wants a specific functionality, he/she will have to include only the relevant file.
On the other hand, I can end up with many header files introduced to the outside world.
Which approach counts as more professional, more correct in software design discipline?
Thank you,
David
I generally implement one header per class. If you find yourself always needing a shotgun blast of headers because you need "one from column A and two from column B", that generally implies some sort of design code smell. For instance, you have a single responsibility spread across several classes instead of concentrated in a single class.
Well, you could always go for option 2 and create a header, that will include all other headers, so that way, if someone doesn't care, he will just include 1 big header, otherwise, he will be able to include only what he needs.
Personally, I don't see anything wrong with one big header, when I try to use small headers as an user, I always have problems like "I need only 1 function from header X, 2 from header Y, ...." and after all, I end up with 15 includes to one library in each *.cpp file, which is annoying (so I actually create one big header myself :) ).
I think that you should implement interface for each class and put them in one header file. No need to produce lot of library headers in the world of precompiled headers.
One header (or few, if there is a lot of interfaces and you can group them logically), but separate classes is an option too. Don't make one huge class with bunch of methods like you were going to do in option 1.
The size of the header file is relevant only in terms of how long it takes to compile. Unused declarations will not impact performance, and your code size is already impacted by shipping all the functions in a DLL instead of statically linking only the needed functions.
Have you considered putting a COM interface on the library? Instead of shipping a separate .h file your users can simply:
#import "mathFunctions.dll" named_guids
Automatically declared smart pointers then make the functions usable with no further manual declarations or even cleanup. You can define your documentation in the IDL, which will then appear in tooltips in the IDE when your clients go to use your code. Your code is also reusable in all Microsoft languages from VB3-6 and wscript and .Net.
double myFunc(double x)
{
double a=1, b=2, c=3, y=0;
MathLib::PolynomPtr polynom(CLSID_CPolynom, 0, CLSCTX_INPROC_SERVER);
y = polynom->someFunction(a, b, c, x); // use it somehow
return y;
}
Used in-proc, COM adds only about 16 cycles of overhead to the execution of each function. Because it's a smart pointer, you do not have to clean it up. And I didn't include it above, but as with anything external you should add basic try/catch functionality wrappers:
catch (_com_error &e) { printf("COM error: %08x %s\n", e.Error(), e.Description()) };
Option 2 would look natural and professional to everybody.
This is the way the large majority of libraries are done.
However, grouping small related classes in the same header (but still having several headers for the whole API) sounds very reasonable.
The biggest disadvantages I see of option 1 are:
- Everything in a big class might be difficult to handle: when a developer is busy on using CPolynom, having its declaration lost between CDifferential and other class would be painful.
- Using a namespace is more appropriate to aggregate classes, than a bigger, "mother" class.
In short, I would choose option 2, with all classes under the library namespace.