Skip to content

Commit 5d831d7

Browse files
author
Joe Gibson
authored
Minor bugfixes and additions to C++ sheet
1 parent dbab509 commit 5d831d7

File tree

1 file changed

+37
-22
lines changed

1 file changed

+37
-22
lines changed

C++ Syntax.md

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,14 @@
4848

4949
## 1.0 C++ Classes
5050
### 1.1 Class Syntax
51-
#### 1.1.1 Class Declaration (`.h` file)
51+
#### 1.1.1 Class Declaration (`polygon.h` file)
5252
Here's a simple class representing a polygon, a shape with any number of sides.
5353

54-
The class *declaration* typically goes in the `.h` file. The *declaration* gives the class name, any classes it may extend, declares the members and methods, and declares which members/methods are public, private, or protected.
54+
The class *declaration* typically goes in the header file, which has the extension `.h` (or, less commonly, `.hpp` to distinguish from C headers). The *declaration* gives the class name, any classes it may extend, declares the members and methods, and declares which members/methods are public, private, or protected. You can think of the declaration as sort of saying: "there will be a thing and here's how it will look like". The declaration is used to inform the compiler about the future essence and use of a particular symbol.
55+
5556
```c++
57+
// File: polygon.h
58+
5659
#include <string>
5760

5861
class Polygon {
@@ -80,14 +83,19 @@ public:
8083
}; // <--- Don't forget the semicolon!
8184
```
8285
83-
#### 1.1.2 Class Definition (`.cpp` file)
86+
#### 1.1.2 Class Definition (`polygon.cpp` file)
87+
The class *definition* typically goes in the `.cpp` file. The *definition* extends the declaration by providing an actual implementation of whatever it is that you're building. Continuing the example from the declaration, the definition can be thought of as saying: "Right, that thing I told you briefly about earlier? Here's how it actually functions". The definition thus provides the compileable implementation.
88+
8489
```c++
85-
#include <string> // explicit is better then implicit
90+
// File: polygon.cpp
8691
87-
#include "Polygon.h" // <--- Obtains the class declaration
92+
#include <string> // <--- Required for std::string
93+
94+
#include "polygon.h" // <--- Obtains the class declaration
8895
8996
// Constructor
9097
// You must scope the method definitions with the class name (Polygon::)
98+
// Also, see the section on the 'explicit' keyword for a warning about constructors with exactly one argument
9199
Polygon::Polygon(const int num_sides, const std::string & name) {
92100
this->num_sides = num_sides; // 'this' is a pointer to the instance of the class. Members are accessed via the -> operator
93101
this->name = name; // In this case you need to use 'this->...' to avoid shadowing the member variable since the argument shares the same name
@@ -114,21 +122,23 @@ void Polygon::SetName(const std::string & name) {
114122
}
115123
```
116124

117-
#### 1.1.3 Class Utilization (Another `.cpp` file)
125+
Regarding the use of `this->` in a class definition, there are places where it's strictly necessary for readability, e.g. when your method parameter shares the exact same name as a member variable, you use `this->` to avoid what's called shadowing. However, some prefer to always use `this->` explicitly regardless of whether it's necessary.
126+
127+
#### 1.1.3 Class Utilization (Some other `.cpp` file)
118128
```c++
119129
#include <string>
120130
#include <iostream>
121131

122132
#include "Polygon.h" // <--- Obtains the class declaration
123133

124-
int main(int argc, char *argv[]) {
134+
int main(int argc, char * argv[]) {
125135
// Create a polygon with 4 sides and the name "Rectangle"
126136
Polygon polygon = Polygon(4, "Rectangle");
127137

128138
// Check number of sides -- Prints "Rectangle has 4 sides"
129139
std::cout << polygon.GetName() << " has " << polygon.GetNumSides() << " sides"<< std::endl;
130140

131-
// Change number of sides to 3 and name to "Triangle"
141+
// Change number of sides to 3 and rename to "Triangle"
132142
polygon.SetNumSides(3);
133143
polygon.SetName("Triangle");
134144
}
@@ -152,22 +162,26 @@ public:
152162
};
153163
```
154164

155-
Another important consideration: If you have getters and setters for all of your members, you may want to reconsider the design of your class. It is more often than not that having getters and setters for every member is indicative of poor planning of the class design and interface. Getters are very common, but setters should be used more carefully. Should you have set the variable in the constructor? Is it set somewhere else in another method, perhaps even indirectly?
165+
This is often used for very basic getters and setters, and also for basic constructors. In contrast, you'll nearly always find more complex methods defined in the `.cpp` file. One exception to this is with class templates, in which the entire templated class declaration and definition must reside in the header file.
166+
167+
Another important consideration: If you have getters and setters for all of your members, you may want to reconsider the design of your class. Sometimes having getters and setters for every member is indicative of poor planning of the class design and interface. In particular, setters should be used more thoughtfully. Could a variable be set once in the constructor and left constant thereafter? Does it need to be modified at all? Is it set somewhere else in another method, perhaps even indirectly?
156168

157169
### 1.2 Inheritance
158170
A class can extend another class, meaning that the new class inherits all of the data from the other class, and can also override its methods, add new members, etc. Inheritance is the key feature required for polymorphism.
159-
P. S. it is very important for a beginner not to overuse this feature(because human's brain tends to create hierarchies,
160-
even where it is not needed). There are some good alternatives like [composition](https://en.wikipedia.org/wiki/Composition_over_inheritance) and [aggregation](https://stackoverflow.com/a/269535)
161171

162-
**Example:** the class `Rectangle` can inherit the class `Polygon`. You would then say that `Rectangle` extends `Polygon`, or that class `Rectangle` is a sub-class of `Polygon`. In plain English, this means that a `Rectangle` is a more specialized version of a `Polygon`.
172+
It is important to note that this feature is often overused by beginners and sometimes unnecessary hierarchies are created, adding to the overally complexity. There are some good alternatives such as [composition](https://en.wikipedia.org/wiki/Composition_over_inheritance) and [aggregation](https://stackoverflow.com/a/269535), although, of course, sometimes inheritance is exactly what is needed.
173+
174+
**Example:** the class `Rectangle` can inherit from the class `Polygon`. You would then say that a `Rectangle` extends from a `Polygon`, or that class `Rectangle` is a sub-class of `Polygon`. In plain English, this means that a `Rectangle` is a more specialized version of a `Polygon`. Thus, all rectangles are polygons, but not all polygons are rectangles.
163175

164-
#### 1.2.1 `Rectangle` Declaration (`.h` file)
176+
#### 1.2.1 `Rectangle` Declaration (`rectangle.h` file)
165177
```c++
166-
#include <string> // explcit is better then implicit
178+
// File: rectangle.h
167179

168-
#include "Polygon.h" // <--- You must include the declaration in order to extend the class
180+
#include <string> // <--- Explicitly include the string header, even though polygon.h also includes it
169181

170-
class Rectangle: public Polygon {
182+
#include "polygon.h" // <--- You must include the declaration in order to extend the class
183+
184+
class Rectangle: public Polygon { // <--- This is 'public inheritance', noted by the 'public' keyword
171185
private: // <--- The members 'num_sides' and 'name' are already inherited from Polygon
172186
int length;
173187
int width;
@@ -189,11 +203,11 @@ public:
189203
};
190204
```
191205
192-
#### 1.2.2 `Rectangle` Definition (`.cpp` file)
206+
#### 1.2.2 `Rectangle` Definition (`rectangle.cpp` file)
193207
```c++
194-
#include <string> // uses std::string
195-
196-
#include "Rectangle.h" // <--- Only need to include 'Rectangle', since 'Polygon' is included in 'Rectangle.h'
208+
// File: rectangle.cpp
209+
210+
#include "rectangle.h" // <--- Only need to include 'Rectangle', since 'Polygon' is included in 'rectangle.h'
197211
198212
// This constructor calls the superclass (Polygon) constructor and sets the name and number of sides to '4', and then sets the length and width
199213
Rectangle::Rectangle(const std::string &name, const int length, const int width) : Polygon(4, name) {
@@ -202,14 +216,15 @@ Rectangle::Rectangle(const std::string &name, const int length, const int width)
202216
}
203217
204218
// This constructor calls the superclass (Polygon) constructor, but sets the length and width to a constant value
205-
Rectangle::Rectangle(const std::string &name) : Polygon(4, name) {
219+
// The explicit keyword is used to restrict the use of the constructor. See section below for more detail
220+
explicit Rectangle::Rectangle(const std::string &name) : Polygon(4, name) {
206221
this->length = 1;
207222
this->width = 1;
208223
}
209224
210225
// Compute the area of the rectangle
211226
const int Rectangle::Area(void) const {
212-
return this->length * this->width;
227+
return length * width; // <--- Note that you don't explicitly need 'this->', you can directly use the member variables
213228
}
214229
```
215230

0 commit comments

Comments
 (0)