Interface vs Class Declarations

Hi all,

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
  class Employee
{

    // Data Members 
        private:
              string name;
              string nI_Number;
              double salary_Gross;
              double tax_Rate;
              double tax_Amount; 
              double salary_Net; 


    // Member Functions 
        public: 

    // Constructors 

           Employee();                                                                         
    // Default Constructor 

           Employee(string nameIN, string nI_NumberIN); 
                                       
    // Overloaded Constructor

           Employee( string nameIN, string nI_NumberIN, double
           salary_GrossIN);   


    // Destructor

           ~Employee();

    // Accessors & Mutators 

            void set_name(string nameIN);

            string get_name(); 
            
            double get_salary_Gross();       



The definitions of member functions in the cpp files are the implementation

e.g
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

//--------- Constructors-----------

Employee::Employee()
{
    cout << "I am the default constructor" << endl;
}

Employee::Employee(string nameIN, string nI_NumberIN)
{
    name = nameIN;                                        
    nI_Number = nI_NumberIN;                    

}

//--------------- Destructor----------------

Employee::~Employee()
{
     cout << "I'm an Object now going out of scope.... Goodbye\n";
      
}


//-------------- Accessors & Mutators ---------------

double Employee::get_salary_Gross()                                                                    
{                                                                                                       
                                                                                                        
    return salary_Gross;
}



Is this correct understanding of the concept? What more do I need to understand that I'm not getting here?

Apologies for the comments this code was taken from a learning exercise on basic class construction.

Thanks for all your help in advance.

You're broadly right, yes.

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.

Does that help?
Last edited on
Hi @MikeyBoy,

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...).
Last edited on
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.)
Last edited on
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?
Last edited on
@MikeyBoy,

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??

Yes, that's exactly what they mean.

(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 :) )
Last edited on
Thanks, Again.
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:
If you're writing a function that can be implemented as either a member or as a non-friend non-member, you should prefer to implement it as a non-member function. That decision increases class encapsulation.
https://www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197


The interface of a class depends on who looks at it:
for authors of derived classes, protected members are part of the interface.
You're welcome. Hope it helped!
Wouldn't the pImpl pattern achieve the same thing more easily?
Yes. It was not a good example. I oversimplified it too far.
Last edited on
Topic archived. No new replies allowed.