LearnCpplus
The Repository Contains the Set Way of Learning Cpplus With the help of programs And Notes.
Install / Use
/learn @mrpawan-gupta/LearnCpplusREADME
Preface
Since the C++ language varies so heavily between versions (e.g. C++0x, C++11, C++17, etc.), I will preface this cheat sheet by saying that the majority of the examples here target C++0x or c++11, as those are the versions that I am most familiar with. I come from the aerospace industry (embedded flight software) in which we purposefully don't use the latest technologies for safety reasons, so most of the code I write is in C++0x and sometimes C++11. Nevertheless, the basic concepts of C++ and object oriented programming still generally apply to both past and future versions of the language.
Table of Contents
| SNo. | Contents | | ------- | ------------ | | 1. |C++ Classes | | 2. |Class Syntax | | 3. |Inheritance | | 4. |Class Polymorphism | | 5. |Special Methods | | 6. |Operator Overloading | | 7. |Templates | | 8. |General C++ Syntax | | 9. |Namespaces | | 10. |References and Pointers | | 11. |Keywords | | 12. |Preprocessor Tokens | | 13. |Strings | | 14. |Iterators | | 15. |Exceptions | | 16. |Lambdas |
<br /><br />
C++ Syntax Cheat Sheet
1.0 C++ Classes
1.1 Class Syntax
1.1.1 Class Declaration (.h file)
Here's a simple class representing a polygon, a shape with any number of sides.
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.
// File: polygon.h
#include <string>
class Polygon {
// Private members and methods are only accessible via methods in the class definition
private:
int num_sides; // Number of sides
// Protected members and methods are only accessible in the class definition or by classes who extend this class
protected:
std::string name; // Name of the polygon
// Public members and methods are accessible to anyone who creates an instance of the class
public:
// Constructors
Polygon(const int num_sides, const std::string & name); // <--- This constructor takes the number of sides and name as arguments
// Getters and Setters
int GetNumSides(void) const;
void SetNumSides(const int num_sides);
std::string & GetName(void) const;
void SetName(const std::string & name);
}; // <--- Don't forget the semicolon!
1.1.2 Class Definition (.cpp file)
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.
// File: polygon.cpp
#include <string> // <--- Required for std::string
#include "polygon.h" // <--- Obtains the class declaration
// Constructor
// You must scope the method definitions with the class name (Polygon::)
// Also, see the section on the 'explicit' keyword for a warning about constructors with exactly one argument
Polygon::Polygon(const int num_sides, const std::string & name) {
this->num_sides = num_sides; // 'this' is a pointer to the instance of the class. Members are accessed via the -> operator
this->name = name; // In this case you need to use 'this->...' to avoid shadowing the member variable since the argument shares the same name
}
// Get the number of sides
int Polygon::GetNumSides(void) const { // The 'const' here tells the compiler that you guarantee that you won't modify the object when this function is called. This allows it to perform optimizations that it otherwise may not be able to do
return this->num_sides;
}
// Set the number of sides
void Polygon::SetNumSides(const int num_sides) {
this->num_sides = num_sides;
}
// Get the polygon name
std::string & Polygon::GetName(void) const {
return this->name;
}
// Set the polygon name
void Polygon::SetName(const std::string & name) {
this->name = name;
}
The getters and setters here don't do much, but you could imagine limiting the number of sides such that it must have at least 3 sides to be a useful polygon, in which case you could enforce that in Polygon::SetNumSides(). Of course, you'd also need to modify the constructor, which could then call SetNumSides() instead of setting the variable directly.
NOTE: 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 usethis->to avoid what's called shadowing. However, some prefer to always usethis->explicitly regardless of whether it's necessary.
1.1.3 Class Utilization (Another .cpp file)
// File: main.cpp
#include <string>
#include <iostream>
#include "Polygon.h" // <--- Obtains the class declaration
int main(int argc, char * argv[]) {
// Create a polygon with 4 sides and the name "Rectangle"
Polygon polygon = Polygon(4, "Rectangle");
// Check number of sides -- Prints "Rectangle has 4 sides"
std::cout << polygon.GetName() << " has " << polygon.GetNumSides() << " sides"<< std::endl;
// Change number of sides to 3 and rename to "Triangle"
polygon.SetNumSides(3);
polygon.SetName("Triangle");
}
1.1.4 Getters and Setters
A shortcut often used for Getters/Setters is to define them in the class declaration (.h) file as follows:
// File: car.h
#include <string>
class Car {
private:
int year;
std::string make;
public:
int GetYear(void) const { return this->year; }
void SetYear(const int year) { this->year = year; }
std::string & GetMake(void) const { return this->make; }
void SetMake(const std::string & make) { this->make = make; }
};
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.
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?
1.2 Inheritance
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.
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 and aggregation, although, of course, sometimes inheritance is exactly what is needed.
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.
1.2.1 Rectangle Declaration (.h file)
// File: rectangle.h
#include <string> // <--- Explicitly include the string header, even though polygon.h also includes it
#include "polygon.h" // <--- You must include the declaration in order to extend the class
// We extend from Polygon by using the colon (:) and specifying which type of inheritance
// will be used (public inheritance, in this case)
class Rectangle : public Polygon {
private:
int length;
int width;
// <--- NOTE: The member variables 'num_sides' and 'name' are already inherited from Polygon
// it's as if we sort of get them for free, since we are a sub-class
public:
// Constructors
explicit Rectangle(const std::string &name);
Rectangle(const std::string &name, const int length, const int width);
// Getters and Setters
const int GetLength(void) const { return this->length; }
void SetLength(const int) { this->length = length; }
const int GetWidth(void) const { return this->width; }
void SetWidth(const int) { this->width = width; }
// <--- NOTE: Again, the getters/setters for 'num_sides' and 'name' are already inherited from Polygon
// Other Methods
const int Area(void) const;
};
NOTE: The inheritance access specifier (
public,protected, orprivate) is used to determine the type of inheritance.
