I was hoping to get some clarification on a piece of conceptual understanding I've been scratching my head about over the last few days. It concerns the common issue of the multiple/different definitions a word can have in C++. I have searched online and read multiple articles which have only sort of added to the confusion, so I'm humbly asking for help on here.
Actual Question
-------------------
What does interface mean as general definition in C++? What is the difference, and where are the overlaps between a declaration in a header file (the signatures of member functions) and what an "interface" is?
- what am I not getting here in regards to the grey area between the two of
them?
My basic understanding is.....
The signatures of a class declared in the header file is the interface e.g
The interface to a class is, basically, anything that other code needs to know, in order to make use of it.
Typically, that means:
- the declaration of the public parts of the class (methods and data members)
- the declaration of any types that are necessary to use the class
- the definition of any variables that are necessary to use the class.
However, the syntax of C++ means that we have to declare the class in one place - we can't declare only the public parts in one file and the private parts (oo-er!) in another. So the class definition in the header file must also include declarations of the private parts even though they aren't, strictly speaking, part of the interface.
thanks a lot for taking the time to explain, it really does help. So when you say anything other code needs to know in order to make use of it, that relates to my understanding of the core purpose header files and member function declarations serve in C++.... which is to tell the pre-compiler that this exists and make use of it when you see a call to it?
Thanks Again, I'm really great for you confirming my gut feeling.
I don't know if this is the 'industry' define of it or not.
But to me, the 'interface', at a high and simple level working definition of it, is 'all the public methods'. (To me this includes public constructors etc).
the true header file for the class has all the stuff, private and all.
you may also have a distributed header file with only the interface (say, you sold the library and gave them a dll file and a .h file, that .h may have the private items removed -- since its already compiled, the internal calls to private things are already resolved and don't need the TRUE header anymore, so the user only needs what the user can access...).
Sort of. The pre-compiler doesn't "know" anything, as such. All the pre-compiler does is construct a new source file, based on the .cpp file modified by any preprocessor directives. Typically, that means:
- it contains all the lines from all the #included files
- #define statements will have been used to replace text that matches the macro names, with the text that was specified in the macro definition
- conditionally compiled code that isn't going to be compiled, will be removed
All the #include statement does is avoid you having to copy and paste code in multiple files. For example, instead of having to copy and paste the definition of a class into every source file that needs it, you can simply have that text in one file, and use a #include statement, so that the preprocessor copies and pastes everything from the included file for you. The preprocessor doesn't interpret any of it - it literally just inserts the text from the header file into the source file.
So, in the most literal sense, the header file should contain everything that is needed for the compiler to be able to compile any code that uses that class.
(Don't ask me how precompiler headers work - I haven't a clue. I had bad experiences using them when I first encountered them *mumble* years ago, and have avoided them ever since. I can't be the only one because every single company I've ever worked at has explicitly avoided using them.)
you may also have a distributed header file with only the interface (say, you sold the library and gave them a dll file and a .h file, that .h may have the private items removed -- since its already compiled, the internal calls to private things are already resolved and don't need the TRUE header anymore, so the user only needs what the user can access...).
Um... I'm not sure that would work, would it? Isn't it often the case that the compiler will need to know the size of the object being used, and what you suggest would cause the compiler to calculate in incorrect size?
EDIT: I guess removing the private method declarations but keeping the private data members would work. It seems like a maintenance headache, though, to have to maintain two different versions of the same header.
Wouldn't the pImpl pattern achieve the same thing more easily?
again thanks..... another lesson for me to follow my gut instincts, I was torn between whether it was the pre-compiler or compiler when I was writing that reply. Thanks again for clarifying that.
@Jonnin
Thank for your clear and to the point explanation. I remember reading about distributed header files before, thanks for putting them in context for me.
Sorry just one more point...... when a person says "separating the interface from the implementation" my understanding of that is having your declarations in a .hpp file and the definitions of member functions in a .cpp file, like in the example I used in my original question. Is the case??
(Occasionally, they may also be talking about using advanced techniques, such as what's known as the "pImpl pattern" to completely hide the private parts of a class definition inside a completely different class. But that's a very specialised thing, and I've seen it used only rarely. So don't worry about it :) )
The interface of a component (or a class) includes all the associated non-member functions and classes supplied along with the component. For instance, the interface of std::string (std::basic_string) includes everythng listed under non-member functions, literals and helper classes mentioned on this page: https://en.cppreference.com/w/cpp/string/basic_string#Non-member_functions
For a well-encapsulated class, there may be many non-member functions which form part of its interface: