Anotações sobre c++
me draw
last edit: 2024-07-27T18:19:07Z

Cpp study notes

All these notes are solely focused on C++. C features and C programming are excluded (to emphasize C++ features, style, and design). Additionally, there is no coverage of introductory OOP concepts.

These notes are a cleaner and straight to the point version, intended for my personal use. Feel free to study from the sources I referenced here. The goal is not to literally teach, but rather to serve as a pocket guide.

Contents

refs

A tour of c++: The Basics

ISO C++ defines two kinds of entities

  • Standard-library
  • Core language and I/O operations

Scope resolution operator

It is used for the following purposes:

  • Access a global variable even with a local variable with the same name.
int temperature = 35;//ºC
int home(){
  int temperature = 10;//ºC
  std::cout << ::temperature; // output 35
  std::cout << temperature;   // output 10
}
  • To define a function outside a class
class Dog{
  public:
    int age;
    void bark();
};

void Dog::bark() { // outside of main function
  std::cout << "wolf wolf wolf wolf";
};
  • To access a class's static variables or namespace variables
class Bottle{
  public:
    static int max_weight;
};
namespace Bag{
  Brush my_Brush;
  int weight;
}
  
int Bottle::max_weight = 5;//L
int main() {
  Bag::weight = 3;//kg
  std::cout << Bag::weight << '\n' << Bottle::max_weight << '\n';
  return 0;
}

// output "3 \n 5 \n"

Class

"The central language feature of C++ is the class"

Stroustrup, Bjarne. The C++ Programming Language. 4th ed., Addison-Wesley, 2013.

class Car {
  public: 
    std::string model;
    float accelerationTimeFrom0To100;
    void showCar();
    Car () {
      std::cout << "Hello World! This is a constructor\n";
    }

  private:
    bool windonIsOpen;
    void openWindow(){
      if(this->windonIsOpen) this->windonIsOpen = false;
      else this->windonIsOpen = true;
    }
    void startEngine();
};

void Car::showCar(){
  std::cout << "showing car\n";
}

int main() {
  Car* car = new Car();
  
  car->showCar();
  std::cout << "Hello World!\n";
}

with "new"

  • alocated in heap
  • acess with "->"
  • need to manage memory alocation

without "new"

  • alocated in stack
  • acess with "."
  • deleted when escope finish

Initializer List

class Point {
  private:
    int x;
    int y;
 
  public:
    Point(int i = 0, int j = 0): x(i), y(j) {}
    /*  can also be written as:
        Point(int i = 0, int j = 0) {
            this->x = i;
            this->y = j;
        }
    */
    int getX() const { return x; }
    int getY() const { return y; }
};

Type of Classes

Concrete classes

It's a class that can be initiate directly. They usually contains complete implementations for all methods. In other words, a concrete class provides implementations for all the methods it declares.

Abstract classes

An abstract class is a class that contains purely virtual methods. This means that the class does not provide implementations for at least one of its methods, making it unable to be instantiated directly. Abstract classes serve as models for other classes that must provide implementations for virtual methods defined in the abstract classe.

class Shape {
  public:
    virtual void draw();
};

class Circle : public Shape {
  public:
    void draw() override {
      std::cout << "Drawing a circle\n";
    }
};

int main() {
    Circle circle;
    circle.draw();
    return 0;
}

Classes in class hierarchies

...

constructor and destructor

class Box {
  
  private:
    int width;
    int height;
    int length;
  
  public:
    Box() {} // constructor
      
    Box(int i){  // constructor
      this->width = i;
      this->height = i;
      this->length = i;
    }

    Box(int width, int height, int length){  // constructor
      this->width = width;
      this->height = height;
      this->length = length;
    }

    ~Box() {  // destructor
      // If any resource has been dynamically allocated, it can be deallocated here
    }

    int Volume() { return this->width * this->height * this->lenght; }
};

Invariants

Enumerations

enum class Color { red, blue , green };
enum class Traffic_light { green, yellow, red };
Color col = Color::red;
Traffic_light light = Traffic_light::red;

You can uso scope resolution operator with Enumerations!

Traffic_light& operator++(Traffic_light& t)
// prefix increment: ++
{
    switch (t) {
      case Traffic_light::green: return t=Traffic_light::yellow;
      case Traffic_light::yellow: return t=Traffic_light::red;
      case Traffic_light::red: return t=Traffic_light::green;
    }
}
Traffic_light next = ++light; // next becomes Traffic_light::green

C++ also offers a less strongly typed ‘‘plain’’ enum (§8.4.2).

Namespaces

  • can be nested

A namespace is a declarative region that provides a scope for identifiers (such as names of types, functions, variables, etc.) within it. Namespaces are used to organize code into logical groups and to avoid name collisions that may occur especially when your codebase includes multiple libraries.

#include <iostream>

namespace BrazilCars{
  class Car{
    public:
      bool leftHandTraffic: true;
  };
}

namespace JapanCars{
  class Car{
    public:
      bool rightHandTraffic: true;
  };
  class Foo{
    public:
      int bee: 0;
  }
}


int main() {
  BrazilCars::Car car1;
  JapanCars::Car car2;
}

inline namespace

inline is a namespace keyword that as if they are changing the scope of your childrens.

namespace Student{
  int age;
  inline namespace Book{
    void readBook(){
      std::cout << "Reading";
    }
  }
}
Student::readBook();

"Using" Directives

Enables names within a namespace to be used without the namespace-name as an explicit qualifier.

using namespace JapanCars;

int main(){
  Car myCar;
}

You can also define to use just a value of this namespace

using JapaCars::Car;

int main(){
  Car myAnotherCar;
}

handling namespace + .h + .cpp

Its like definition of structure, you can define the implementation of a method, fuction, ... inside a .h (inside of a definition of structure, class or namespace), but isn't a better pratice. If you will define your namespace (or class, struct, whatever) in a .h, the best way is define this methods in .c file. With this, you will use :: operator (Scope resolution operator)

// main.c
#include <iostream>
#include "./FooBar.hpp"

int main() {
  std::cout << "Hello World!\n";
  std::cout << FooBar::Bar() << std::endl;
}
// FooBar.hpp
#pragma once
namespace FooBar
{
    void Foo();
    int Bar();
}
// FooBar.cpp
#include "./FooBar.hpp"

int FooBar::Bar(){
  return 0;
}

Error Handling

Exceptions

  • throw
  • try-catch

Overloading Operators

Examples

class MyClass {
  private:
    int value;
  public:
    MyClass(int val) : value(val) {}
    MyClass operator+(const MyClass& other) const {
      return MyClass(value + other.value);
    }
    void print() const { std::cout << "Value: " << value << std::endl; }
};

int main() {
  MyClass obj1(5);
  MyClass obj2(3);

  MyClass result_add = obj1 + obj2;

  result_add.print();  // Output: Value: 8

  return 0;
}
std::string operator*(const std::string& str, int multiplier) {
  std::string result;
  for (int i = 0; i < multiplier; ++i) {
    result += str;
  }
  return result;
}

std::string operator*(int multiplier, const std::string& str) {
  return str * multiplier;
}

int main() {
  std::string s = "abc";
  int n = 3;

  std::string repeated = n * s;

  // Output: "abcabcabc"
  std::cout << "Resultado: " << repeated << std::endl;

  return 0;
}

All operators you can overload

  • Aritmetic:

    • + (addition)
    • - (subtraction)
    • * (multiplication)
    • / (division)
    • % (modulo)
  • Assignment:

    • = (assignment)
    • += (addition assignment)
    • -= (subtraction assignment)
    • *= (multiplication assignment)
    • /= (division assignment)
    • %= (modulo assignment)
  • Increment/Decrement:

    • ++ (pre-increment and post-increment)
    • -- (pre-decrement and post-decrement)
  • Comparison:

    • == (equality)
    • != (inequality)
    • < (less than)
    • > (greater than)
    • <= (less than or equal to)
    • >= (greater than or equal to)
  • Logical/Bitwise:

    • ! (logical NOT)
    • && (logical AND)
    • || (logical OR)
    • & (bitwise AND)
    • | (bitwise OR)
    • ^ (bitwise XOR)
    • ~ (bitwise NOT)
    • << (left shift)
    • >> (right shift)
  • Others:

    • () (function call)
    • [] (array indexing)
    • -> (member access through pointer)
    • , (comma, expression separator)

Templates

"A template is a class or a function that we parameterize with a set of types or values"

Stroustrup, Bjarne. The C++ Programming Language. 4th ed., Addison-Wesley, 2013.

  • Dinamic type templates

    • Template Metaprogramming
    • SFINAE (Substitution Failure Is Not An Error)
    • Common Mistakes and Best Practices
  • Fixed type templates

    • Template argument deduction
    • Template specialization
    • Templates with fixed data types

alias template

You can write, usign directive to create a alias type for template

template<typename T>
void print(const T& value) {
  using MyType = T;
  MyType MyValue = value;
  std::cout << "Value: " << MyValue << std::endl;
}

int main(){
  print<float>(10.5);
  print<int>(10);
  print(10.1); // Template argument deduction
}
me profile picture draw

Francisco Ossian

Desenvolvendo ideias e criando soluções

Browse
  • Blog
  • Work
  • Home
Services
  • Desenvolvimento Front-end
  • Desenvolvimento Mobile
  • Automação de Processos
  • Desenvolvimento de APIs
  • Consultoria e Auditoria de Código
  • Desenvolvimento de Ferramentas e Utilitários
  • Criação de Blogs e Conteúdo Técnico
Contact
  • /github-icon.svg
  • /linkedin-icon.svg
  • /email-icon.svg
  • /wpp-icon.svg