Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add class info for headers concept #727

Merged
merged 2 commits into from
Oct 18, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 55 additions & 9 deletions concepts/headers/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,33 +13,79 @@ Some projects use `.hpp` or skip the extension completely.
The definitions are located in a separate `.cpp` file.
To reunite both parts, this source file starts by including the respective header file.

If you want to write a library called "myLib", that offers a function "my_func" that returns your favorite number, the files would look like this:
If you want to write a library called "quick_math", that offers a function "super_root" that you want to use often, the files would look like this:

```cpp
// A file named myLib.h
// A file named quick_math.h
#pragma once
namespace magic {
int my_func(int a, int b);
namespace quick_math {
double super_root(double x, int n);
}
```

```cpp
vaeng marked this conversation as resolved.
Show resolved Hide resolved
// A file named myLib.cpp
#include "myLib.h"
int magic::my_func(int a, int b) {
return 47 * a + 3 * b;
// A file named quick_math.cpp
#include "quick_math.h"
#include <cmath>
double quick_math::super_root(double x, int n) {
while(n) { x = sqrt(x), --n;}
return x;
}
```

If you need to include another header, that is only needed by the implementation, the respective `#include` line is only needed in the source file.
Everything that is included in the header, is also available in the `.cpp` file, like the `string` library in the example below.
Attention: the `;` is needed after the declaration in the header file, but not after the definition in the source file.

~~~~exercism/note
Many C++ exercises on Exercism start with two almost empty files: header and source.
You have to check the `*_test.cpp` file to see the names and namespaces of the expected functions to solve the exercise.
~~~~

## Classes and Headers

Classes can become very complex.
Many developers separate the public interface from the inner workings.
Often, all declarations are decoupled from the implementation via header and source files, but there are some exceptions.
The split between those two might seem arbitrary and the following example can give some guidance.

```cpp
// A file named robot_flower.h
#if !defined(ROBOT_FLOWER_H)
#define ROBOT_FLOWER_H
#include <string>
namespace robots {
class Flower {
private:
bool needs_water{};
int size{};
std::string name{};
public:
Flower(std::string name, int size = 0);
void give_water() {needs_water = false;}
std::string get_name() {return name;}
int get_size() {return size;}
void start_next_day();
};
}
#endif
```

```cpp
// A file named robot_flower.cpp
#include "robot_flower.h"
robots::Flower::Flower(std::string name, int size) {this->name = "Robotica " + name; this->size = size;}
void robots::Flower::start_next_day() {if (!needs_water) ++size; needs_water = true;}
```

Member variables are usually kept in the header together with the implementation of trivial member functions.
The simple `give_water`, `get_name` and `get_size` functions are so small, that one would not move them into the `.cpp` file.
The constructor and the `start_next_day` functions shall be considered more _complex_ in this example and have thus been moved.
The definitions are prefixed with the namespace `robots` and the class type `Flower`.

## Include Guards

You may have noticed the `#pragma once` line in the example header file above.
This include guard ensures that the content of the file is included only once during the compilation to avoid errors.
There is another, more complex variation that starts with `#ifndef` which serves the same purpose.
There is another, more complex variation that starts with `#if !defined` and ends with `#endif`.
It serves the same purpose and its usage is shown in the `Flower` class example above.
4 changes: 4 additions & 0 deletions concepts/headers/links.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,9 @@
{
"url": "https://learn.microsoft.com/en-us/cpp/cpp/header-files-cpp?view=msvc-170",
"description": "Examples and information on header files and include guards"
},
{
"url": "https://www.learncpp.com/cpp-tutorial/classes-and-header-files/",
"description": "More information about classes in header files"
}
]