Including headers just for private data in a .h file - c++

I have a class defined in class.cpp and class.h. The class uses some structures/classes/types/whatever defined in stuff.h (and of course, stuff.cpp) for private members and methods. My main program is in main.cpp, which #includes class.h, but doesn't care about anything in stuff.h. If it makes a difference, class.cp is supposed to be loaded dynamically (.dll/.so).
I would ideally like to have the stuff.h only included in class.cpp and stuff.cpp linked only to this file, as they would just cause name-space pollution in main.cpp and extra bloat by being linked to the final program.
The problem is that I have to include stuff.h in class.h, since it's definitions are used in the private: part of my class, which is all in class.h. And since main.cpp brings in class.h, it also gets stuff.h!
I hope this was clear. In C# this can be solved by partial classes. How would I do this in C++?

You do that in C++ by using pImpl aka Opaque Pointers where the class you expose only have one attribute which is a partially defined struct (sometimes people uses void* instead, but to same efefct).
The partially defined struct, then is fully defined inside your stuff.cpp and everything works as you expect -- the only snag is that you need to make sure that you constructor and destructor new/delete the internal implementation, and you need to make special provisions in your copy constructor and and your assignment operator operator= -- most people opt for just make the copy constrctor and assignment operators private, so that the compiler will object if they are used.

Looks like you need Pimpl Idiom here. The main idea of Pimpl is that you forward declare class with implementation instead of including it's definition. This allows you to remove dependencies on implementation in header files, which usually results in compilation speed up, especially on large projects.

Related

Can I use a slim version of my header to be included with the library?

What I mean is my real header file can look like this:
#include "some_internal_class.h"
class MyLibrary {
Type private_member;
void private_function();
public:
MyLibrary();
void function_to_be_called_by_library_users();
};
Now I want to produce a dynamic library containing all the necessary definitions. and I want to ship with it a single header instead of shipping every single header I have in my library.
So I was thinking I could create a slim version of my header like so:
class MyLibrary {
public:
MyLibrary();
void function_to_be_called_by_library_users();
};
Headers are just declarations anyway right? they're never passed to the compiler. And I've declared what the user will be using.
Is that possible? If not, why not?
This is a One Definition Rule violation. The moment you deviate by a single token.
[basic.def.odr]/6
There can be more than one definition of a class type, [...] in a
program provided that each definition appears in a different
translation unit, and provided the definitions satisfy the following
requirements. Given such an entity named D defined in more than one
translation unit, then
each definition of D shall consist of the same sequence of tokens; and
Your program may easily break if you violate the ODR like that. And your build system isn't at all obligated to even warn you about it.
You cannot define a class twice. It breaks the One Definition Rule (ODT). MyLibrary does that, unfortunately.
they're never passed to the compiler
They will. Members of a class must be known at compile time, so that the compiler can determine the class's size.
Header are just declarations anyway right? they're never passed to the
compiler. And I've declared what the user will be using.
No. Headers are part of source code and are compiled together with source files. They contain the information necessary for a compiler to understand how to work with code (in your case, with class MyLibrary).
As an example, you want library users to be able to create objects of class MyLibrary, so you export the constructor. However, this is not sufficient: the compiler needs to know the size of the object to be created, which is impossible unless you specify all the fields.
In practice, deciding what to expose to library users and what to hide as implementation details is a hard question, which requires detailed inspection of the library usage and semantics. If you really want to hide the class internals as implementation detail, here are some common options:
The pimpl idiom is a common solution. It enables you to work with the class as it is usually done, but the implementation details are nicely hidden.
Extract the interface into an abstract class with virtual functions, and use pointers (preferably smart pointers) to work with the objects.
Headers are just declarations anyway right? they're never passed to the compiler.
The moment you do a #include to a file, its content are copied and pasted into your source file exactly as they are.
So even though you don't pass them directly as compiler arguments, they're still part of your code and code in them will be compiled into your translation units.
Solutions by #lisyarus are pretty good.
But another option would be doing it the C way. Which is the most elegant in my opinion.
In C you give your users a handle, which will most likely be a pointer.
Your header would look something like this:
struct MyLibrary;
MyLibrary*
my_library_init();
void
my_library_destroy(MyLibrary*);
void
my_library_function_to_be_called_by_library_users(MyLibrary*);
A very small and simple interface that does not show your users anything you don't want them to see.
Another nice perk is that your build system will not have to recompile your whole program just because you added a field to the MyLibrary struct.
You have to watch out though, because now you have to call my_library_destroy which will carry the logic of your destructor.

C++ Declaration of class variables in header or .cpp?

So far, I've been using classes the following way:
GameEngine.h declares the class as follows
class GameEngine {
public:
// Declaration of constructor and public methods
private:
InputManager inputManager;
int a, b, c;
// Declaration of private methods
};
My GameEngine.cpp files then just implement the methods
#include "____.h"
GameEngine::GameEngine() {
}
void GameEngine::run() {
// stuff
}
However, I've recently read that variable declarations are not supposed to be in the header file. In the above example, that would be an inputManager and a, b, c.
Now, I've been searching for where to put the variable declarations, the closest answer I found was this: Variable declaration in a header file
However, I'm not sure if the use of extern would make sense here; I just declare private variables that will only be used in an instance of the class itself. Are my variable declarations in the header files fine? Or should I put them elsewhere? If I should put them in the cpp file, do they go directly under the #include?
Don't confuse a type's members with variables. A class/struct definition is merely describing what constitutes a type, without actually declaring the existence of any variables, anything to be constructed on memory, anything addressable.
In the traditional sense, modern class design practices recommend you pretend they are "black boxes": stuff goes in, they can perform certain tasks, maybe output some other info. We do this with class methods all the time, briefly describing their signature on the .h/.hpp/.hxx file and hiding the implementation details in the .cpp/.cc/.cxx file.
While the same philosophy can be applied to members, the current state of C++, how translation units are compiled individually make this way harder to implement. There's certainly nothing "out of the box" that helps you here. The basic, fundamental problem is that for almost anything to use your class, it kind of needs to know the size in bytes, and this is something constrained by the member fields and the order of declaration. Even if they're private and nothing outside the scope of the type should be able to manipulate them, they still need to briefly know what they are.
If you actually want to hide this information to outsiders, certain idioms such as PImpl and inlined PImpl can help. But I'd recommend you don't go this way unless you're actually:
Writing a library with a semi-stable ABI, even if you make tons of changes.
Need to hide non-portable, platform-specific code.
Need to reduce pre-processor times due to an abundance of includes.
Need to reduce compile times directly impacted by this exposure of information.
What the guideline is actually talking about is to never declare global variables in headers. Any translation unit that takes advantage of your header, even if indirectly, will end up declaring its own global variable as per header instructions. Everything will compile just fine when examined individually, but the linker will complain that you have more than one definition for the same thing (which is a big no-no in C++)
If you need to reserve memory / construct something and bind it to a variable's name, always try to make that happen in the source file(s).
Class member variables must be declared in the class definition, which is usually in a header file. This should be done without any extern keywords, completely normally, like you have been doing so far.
Only variables that are not class members and that need to be declared in a header file should be declared extern.
As a general rule:
Variables that are to be used with many functions in the same class go in the class declaration.
Temporary variables for individual functions go in the functions themselves.
It seems that InputManager inputManager; belongs in the class header.
int a, b, c; is harder to know from here. What are they used for? They look like temporary variables that would be better off in the function(s) they're used in, but I can't say for sure without proper context.
extern has no use here.

Do I have to mention private methods in the header file of a class?

For now I do not use header files at all. Classes are each in a single .cpp file completely. But to save compile time I want to make use of header files now. My hope is that Visual Studio won't compile classes which weren't modified for debug builds then.
Is there a way to mention only public methods and members in the header file. In theory that would be enough information for the compiler. If another file, say main.cpp includes the class header there is no need for private methods and members, is it?
How can I use header files without retyping the names of private methods and members? The reasons for me to want so is coding productivity. When I want do add a small helper function to the class used by another method, I don't want to have to also add it's signature to the header file.
If another file, say main.cpp includes the class header there is no need for private methods and members, is it?
No, public methods and members aren't necessarily enough. For example, if another .cpp file were to try and create an instance of your class:
SomeClass instance;
the compiler will need to know, among other things, how much memory to allocate for SomeClass. For that it requires full knowledge of SomeClass's private data members.
The way you are framing the question makes it sound as if you were intent on fighting the language. I don't think that's a good way to go about it. I think the best way is to do things the way things are usually done in the language of your choice, and depart from that only when there is a specific, clearly understood need.
The way things are usually done in C++ is that the entire class declaration goes in the header file, and the definition is in some way split between the header file and the corresponding .cpp file. The exact split is determined by various technical considerations. For example, templates and inline functions normally have to appear in the header file. On the other hand, placing code in header files increases dependencies and potentially build times.
There are ways to address these issues. However, since this involves extra complexity, I'd argue that this should only be done if there is a clearly identifiable need.
I don't know of a way to do what you're asking, but there is another way to give some isolation. You might want to take a look at the pimpl idiom as it offers isolation about private information. It's a little bit of extra work, but it can be extremely useful, especially in large projects.
All function declarations should go in header files and all function definitions should go in cpp files. It's not good coding practice to put declarations inside the cpp files.
You could put definitions inside headers though, when you write templates or inline functions.
Once you declare the class in the header file, you have to declare all its methods and members inside the class' declaration in the header, given that your class is no longer declared in the cpp file.

Where should support function declarations go?

I have a .cpp source file with some functions that need to be publicly accessible and some support functions that are only used in this source file.
I have been putting the all of these functions declarations in the header file as I personally find it useful to see everything a class offers in one place. However I would like to indicate whether the functions are for internal use, similar to the private access modifier, but without using classes (they are standalone functions).
Some possible solutions are:
Put the private declarations in the source file.
Put the private declarations in a separate header.
Both of these solutions split the public and private functions into separate files which I would like to avoid.
If the functions are not intended for public use, the shouldn't be placed into the header. Put them into the source file they are used in.
To completely hide these functions from being used outside the source file one of the following is usually done:
Functions are declared as static.
Functions are put into an unnamed namespace.
The latter is considered preferable. Actually, the C++ Standard 7.3.1.1 states:
The use of the static keyword is deprecated when declaring objects in a namespace scope, the unnamed-namespace provides a superior alternative.
For more discussion about unnamed namespaces vs static refer to Unnamed/anonymous namespaces vs. static functions and to corresponding comp.lang.c++.moderated thread.
If the private functions are only used in a single source file, then you don't need any extra header file. Just mark the functions either static or use an anonymous namespace.
If the functions can be used from many source files, declare them in a separate header file in a special namespace. That's my advice.
Where should support function declarations go?
They don't have to go anywhere. Make them static and keep them in source file. If they're only used in single source file, there's no need to put forward declarations into any header.
You don't mention whether these 'functions' are members of a class but I'll assume that they are. If so, I would recommend that you look at the 'pimpl idiom'. Basically this means putting all or most of what you want to keep private into a seperate class and then only having a pointer to an instance of the class in your class declaration. For example:
class MyClass
{
// ... some stuff
private:
SecretObject obj_;
int hiddenCall();
};
becomes
class MyClassImpl;
class MyClass
{
private:
MyClassImpl* impl_;
};
The idea then is that all the declaration and definition of your implemntation class would go into your .cpp file which hides it from anything but the compilation unit. This approach has a number of important advantages:
Hides implementation so the publicly available header does not give too much of the implementation away.
Can increase compilation speed by removing dependecies in the header - v. important if the header is included a lot.
Can be useful for 'insulating` client code against libraries that they shouldn't need to build against such as database APIs etc.
There are a number of drawbacks:
Can make unit testing more tricky if code is hidden away in cpp files. Personally I find a better solution is to have a seperate, private header and implementation file so you can control what clients of your code get but a test harness can still test it adequately. You can simply include the MyClassImpl header in your cpp file, but don't include it in the MyClass header - this would defeat the object.
The indirection between MyClass and MyClassImpl can be tiresome to code / manage.
Generally though, it's probably the best way of acheiving what you want to get to. Look at articles by Herb Sutter for a more in depth explaination.
On the other hand, if you are talking about free functions, not directly related to the class, then I would put these within the unnamed namespace within your cpp file. For example:
namespace {
// Your stuff goes here.
};
Again, you've got a unit test issue of how to access these functions if you take this approach, but it's possible to work around this if that's really an issue, perhaps by creating a specific namespace, conditional compilation etc. Not ideal, but possible.

Member function definition

What is the right approach to take:
Define the member (class) function inside the class?
Define the member (class) function outside the class?
Thanks.
Assuming you're talking about these three possibilities:
Method defined in class definition in header file.
Method define outside class definition in header file.
Method define outside class definition in implementation file.
Then project and company guidelines may force you to use (1) or (3) always.
When you have a choice, it's IMHO best to adapt to circumstances at hand, considering things such as
Do you want a header-only module? Then (1) as default, (2) possible.
Is the method a large beast? Then (2) or (3).
Template method specialization? Then (2) or (3).
There is a build-time problem (slow builds)? Indicates (3).
Template class? (1) or possibly (2)
But except where the choice is effectively forced on you, above all consider the clarity of your code.
Cheers & hth.,
A common advice is to keep headers as simple and clean as possible. Headers will be included by external code, and they will have to process everything that you have written there. If you write a method in the header, all translation units will compile that function, only so that the linker can discard all but one of them later on.
If your code has an internal dependency on a type or library that is not part of your interface, then by inlining the code of the member function in the class declaration the definition of that class or the headers of that library will have to be included in your header, and that means that you are leaking your implementation details to your users.
Unless the member function definition is trivial (in an informal sense) and doesn't introduce any additional dependencies I would normally define a member function outside of the class body in a separate source file.
It's often a matter of style but there are some cases in which it is necessary and many other cases in which it is desirable to define function outside of the class body.
For example, in the cases where you have interdependent classes and only a forward declaration of another class can be made available before the class definition, a member function which uses the definition of that other class can only be defined outside of the class body after a full definition of the other class has been provided.
Do you mean "in the class declaration / .h file" vs "in a .cpp file using ::" ?
If so I always go for the latter. When it comes to debugging, it's a lot easier to step through and see what's going on. It also helps declutter the class declaration, which doesn't need to know any implementation details"
If you want to define a function within a class the most basic syntax looks generally like:
class Object
{
int property;
void doSomething()
{
property=100;
}
};
If you want to define a function outside it is similar to declaring functions before main and in library files. In your class you have:
class Object
{
int property;
void doSomething();
};
Then somewhere after your class, after the main() function or in an included file you can have the definition:
void Object::doSomething()
{
property=100;
}
Some place classes in a header file and the definitions in a cpp file used by that header. Various techniques possible.
Both of these approaches are valid. Often I will include very small and/or core class functionality directly within the class and other functions which do heavier bulk work I tend to separate. Try to think the difference in coming upon your code and wanting to alter it.
if we see according to performance issue than it is more effective way to declare the function in the class . becouse at the compile time it conects all the funcation calls and other components so it will easy and must be faster to get all in one source...