Example header and cpp file

Example header and cpp file

In this section, we demonstrate how to make class reusable by separating it into another files.

Header File

Class declarations are stored in a separate file. A file that contains a class declaration is called header file. The name of the class is usually the same as the name of the class, with a .h extension. For example, the Time class would be declared in the file Time .h.

#ifndef TIME_H #define TIME_H class Time < private : int hour; int minute; int second; public : //with default value Time(const int h = 0, const int m = 0, const int s = 0); // setter function void setTime(const int h, const int m, const int s); // Print a description of object in " hh:mm:ss" void print() const; //compare two time object bool equals(const Time&); >; #endif

Implementation File

The member function definitions for a class are stored in a separate .cpp file, which is called the class implementation file. The file usually has the same name as the class, with the .cpp extension. For example the Time class member functions would be defined in the file Time.cpp.

#include #include #include "Time.h" using namespace std; Time :: Time(const int h, const int m, const int s) : hour(h), minute (m), second(s) <> void Time :: setTime(const int h, const int m, const int s) < hour = h; minute = m; second = s; >void Time :: print() const < cout bool Time :: equals(const Time &otherTime)

Client Code

client code, is the one that includes the main function. This file should be stored by the name main.cpp

#include using namespace std; #include "Time.h" int main() < Time t1(10, 50, 59); t1.print(); // 10:50:59 Time t2; t2.print(); // 06:39:09 t2.setTime(6, 39, 9); t2.print(); // 06:39:09 if(t1.equals(t2)) cout

The advanages of storing class definition in separate file are

Читайте также:  Алгоритм раскраски графа python

2. The clients of the class know what member functions the class provides, how to call them and what return types to expect

3. The clients do not know how the class's member functions are implemented.

Источник

Header files (C++)

The names of program elements such as variables, functions, classes, and so on must be declared before they can be used. For example, you can't just write x = 42 without first declaring 'x'.

int x; // declaration x = 42; // use x 

The declaration tells the compiler whether the element is an int , a double , a function, a class or some other thing. Furthermore, each name must be declared (directly or indirectly) in every .cpp file in which it is used. When you compile a program, each .cpp file is compiled independently into a compilation unit. The compiler has no knowledge of what names are declared in other compilation units. That means that if you define a class or function or global variable, you must provide a declaration of that thing in each additional .cpp file that uses it. Each declaration of that thing must be exactly identical in all files. A slight inconsistency will cause errors, or unintended behavior, when the linker attempts to merge all the compilation units into a single program.

To minimize the potential for errors, C++ has adopted the convention of using header files to contain declarations. You make the declarations in a header file, then use the #include directive in every .cpp file or other header file that requires that declaration. The #include directive inserts a copy of the header file directly into the .cpp file prior to compilation.

In Visual Studio 2019, the C++20 modules feature is introduced as an improvement and eventual replacement for header files. For more information, see Overview of modules in C++.

Example

The following example shows a common way to declare a class and then use it in a different source file. We'll start with the header file, my_class.h . It contains a class definition, but note that the definition is incomplete; the member function do_something is not defined:

Next, create an implementation file (typically with a .cpp or similar extension). We'll call the file my_class.cpp and provide a definition for the member declaration. We add an #include directive for "my_class.h" file in order to have the my_class declaration inserted at this point in the .cpp file, and we include to pull in the declaration for std::cout . Note that quotes are used for header files in the same directory as the source file, and angle brackets are used for standard library headers. Also, many standard library headers do not have .h or any other file extension.

In the implementation file, we can optionally use a using statement to avoid having to qualify every mention of "my_class" or "cout" with "N::" or "std::". Don't put using statements in your header files!

// my_class.cpp #include "my_class.h" // header in local directory #include // header in standard library using namespace N; using namespace std; void my_class::do_something()

Now we can use my_class in another .cpp file. We #include the header file so that the compiler pulls in the declaration. All the compiler needs to know is that my_class is a class that has a public member function called do_something() .

// my_program.cpp #include "my_class.h" using namespace N; int main()

After the compiler finishes compiling each .cpp file into .obj files, it passes the .obj files to the linker. When the linker merges the object files it finds exactly one definition for my_class; it is in the .obj file produced for my_class.cpp, and the build succeeds.

Include guards

Typically, header files have an include guard or a #pragma once directive to ensure that they are not inserted multiple times into a single .cpp file.

// my_class.h #ifndef MY_CLASS_H // include guard #define MY_CLASS_H namespace N < class my_class < public: void do_something(); >; > #endif /* MY_CLASS_H */ 

What to put in a header file

Because a header file might potentially be included by multiple files, it cannot contain definitions that might produce multiple definitions of the same name. The following are not allowed, or are considered very bad practice:

  • built-in type definitions at namespace or global scope
  • non-inline function definitions
  • non-const variable definitions
  • aggregate definitions
  • unnamed namespaces
  • using directives

Use of the using directive will not necessarily cause an error, but can potentially cause a problem because it brings the namespace into scope in every .cpp file that directly or indirectly includes that header.

Sample header file

The following example shows the various kinds of declarations and definitions that are allowed in a header file:

// sample.h #pragma once #include // #include directive #include namespace N // namespace declaration < inline namespace P < //. >enum class colors : short < red, blue, purple, azure >; const double PI = 3.14; // const and constexpr definitions constexpr int MeaningOfLife< 42 >; constexpr int get_meaning() < static_assert(MeaningOfLife == 42, "unexpected!"); // static_assert return MeaningOfLife; >using vstr = std::vector; // type alias extern double d; // extern variable #define LOG // macro definition #ifdef LOG // conditional compilation directive void print_to_log(); #endif class my_class // regular class definition, < // but no non-inline function definitions friend class other_class; public: void do_something(); // definition in my_class.cpp inline void put_value(int i) < vals.push_back(i); >// inline OK private: vstr vals; int i; >; struct RGB < short r< 0 >; // member initialization short g< 0 >; short b< 0 >; >; template // template definition class value_store < public: value_store() = default; void write_value(T val) < //. function definition OK in template >private: std::vector vals; >; template // template declaration class value_widget; > 

Feedback

Submit and view feedback for

Источник

How to Create Header Files in C++

How to Create Header Files in C++

If you are a C++ programmer, then you must have used predefined header files like , , etc.

In this article, I have shown how to create your own header files in the right way.

This article is divided into two sections -

Creating Ordinary Header Files

Suppose you have created the following header file with the following line in it-

const int SOME_CONSTANT = 50; // first.h // . More 

Now you have a second header file which has included the above file -

#include "first.h" // second.h // . More 

And you have one more C++ file which includes both these files -

#include "first.h" // third.cpp #include "second.h"  // . More 

Now, when you compile your third.cpp file, you will get an error like this -

error: redefinition of ‘const int SOME_CONSTANT’ 1 | const int SOME_CONSTANT = 50;

Because the first.h file is included twice, therefore its content also gets copied twice in the third.cpp file.

To prevent this we should use Header Guards.

Using Header Guards

Header Guards are conditional compilations directives which mean they are evaluated at compilation time and the compiler will perform operations on the basis of its result.

Header Guards look like this -

#ifndef HEADERFILE_H #define HEADERFILE_h // Declarations goes here #endif 

ifndef means if not defined, if the HEADERFILE_H is not defined it will define it, otherwise if it is already defined it will skip compiling everything between ifndef and endif .

Now, we will update our previous example with header guards

#ifndef FIRST_H #define FIRST_H const int SOME_CONSTANT = 50; // . More #endif 
#ifndef SECOND_H #define SECOND_H #include "first.h" // . More #endif 
#include "first.h" #include "second.h" #include int main() < // Using first.h and second.h > 

Now, our third.cpp file will compile without error.

One Complete Example

Let's look at one more example -

In this example, we will create the following three files -

  • headerfiles.h - Provides constants, functions and class declarations for use.
  • definitions.cpp - Contains definitions for the headerfiles.h functions and classes.
  • main.cpp - Consumes the functions and classes declared in headerfiles.
headerfile.h
#ifndef HEADERFILE_H #define HEADERFILE_H #include #include const int SOME_CONSTANT = 50; void print(std::string message); class SomeClass private: int var; public: SomeClass(int var); void print(); >; #endif 
definitions.cpp
#include "headerfile.h" void print(std::string message) < std::cout "Message hljs-string">"\n"; > SomeClass::SomeClass(int var) < this->var = var; > void SomeClass::print() < std::cout "var hljs-string">"\n"; > 
main.cpp
#include "headerfile.h" #include int main() < print("Hello, World"); // OUTPUT: Message = Hello, World SomeClass object(50); object.print(); // OUTPUT: var = 50 std::cout "\n"; // OUTPUT: 50 return 0; > 

This is the right way to create header files, you separate the declarations and definitions in two files and only include the header file when necessary.

You will link the definitions file when compiling like this -

g++ -o main main.cpp definitions.cpp

Creating Template Header Files

Now in case of templates, you can't simply create two different files for declarations and definitions like the previous example because, when compilers compile the program it needs to replace the generic types with the required template arguments.

# foo.h template typename type> type sum(type a, type b) < type result = a + b; return result; > # main.cpp sum(50, 100); // This will create a function sum with type replaced with int everywhere 

If we haven't provided the definition in the header file, the compiler won't be able to do perform the replacement(or instantiation).

Now, to separate our definition and declaration in the case of templates we can use the following way -

max.h

Header file to store function and class declaration

#ifndef MAX_H #define MAX_H template typename type> type max(type a, type b); #include "max.tpp" // IMPORTANT: We are including our definitions in the header file at the end #endif 
max.tpp

Definition file, note that its extension is .tpp and not .cpp as per the convention for template definitions files.

#include "max.h" template typename type> type max(type a, type b) < return a > b ? a : b; > 
main.cpp
#include "max.h" #include int main() < std::cout 50, 100) "\n"; // 100 return 0; > 

Thanks for reading

References:

You may also like:

Источник

Оцените статью