Quick C++

Posted on July 1, 2014
Tags: c

1 CMakeList

First install mvs-code CMake toolkit

1.1 Quick Start

  1. >CMake: Quick Start > Select kitsGCC 11.2.1 x86.. > Input Name of project > Select Executable
    • Optional Changing compiler: >CMake: Configure > Select GCC 11.2.1 x86..
  2. >CMake: Select Variant > Select Release
  3. >Cmake: Make Build

Go to /build dir and run the executable.

2 Starter

#include <bits/stdc++.h>
template <typename T>
void print(const T &t) {
    std::cout << t << std::endl;
}
template <typename O,typename T>
void print(const O label, const T &t) {
    std::cout << label << ": " << t << std::endl;
}
template <typename T>
void print(const std::vector<T>& t) {
    for(auto i: t){
        std::cout << i << " ";
    }
  std::cout <<std::endl;
}
template <typename O,typename T>
void print(const O label,const std::vector<T>& t) {
    std:: cout << label << ": ";
    for(auto i: t){
        std::cout << i << " ";
    }
  std::cout <<std::endl;
}
template <typename T, typename R, typename L>
void fmap(const T& t, R& result, L lambda ){
    transform(t.cbegin(),t.cend(),result.begin(),lambda);
}
template <typename T, typename B, typename L>
auto foldl(const T& t, const B base, L lambda ){
    return accumulate(t.cbegin(),t.cend(),base,lambda);
}

template <typename T, typename B, typename L>
auto foldr(const T& t, const B base, L lambda ){
    return accumulate(t.crbegin(),t.crend(),base,lambda);
}

//functional format instead of  int maxd(){}, we  do auto maxd()-> int{}
auto maxd(int a, int b) -> int{
    return 5;
}

using namespace std;
int main(){    
//--------------------------------------------------------
    //lambda  
    auto lambdaX = [](int x){return x + 9;};
    print("lambda applied to 8",lambdaX(8)); 
    print("lambda type", typeid(lambdaX).name()); //type of lambda

    //lambda expression  = (lambda a: a + 9)(8)
    int pp = [](int x){return x + 9;}(8);
//--------------------------------------------------------
    vector<int> intlst = {1,2,3,4};
    vector<int> results(intlst.size());
    //cbegin and begin are iterators
    //cbegin is constant, begin is not, begin iterator can change the value pointing to
    //fmap is a template for transform
    transform(intlst.cbegin(),intlst.cend(),results.begin(),[](int x){return x + 3;});
    fmap(intlst,results,[](int x){return x + 3;});
    print("transform",results);
//--------------------------------------------------------   
    //accumulate is foldl, the state transition fold
    auto Sum = accumulate(intlst.cbegin(),intlst.cend(),0,[](int x, int y){return x + y;});
    auto Sum2 = foldl(intlst,0,[](int x, int y){return x + y;});
    print("accumulate",Sum2);
    print("foldl",Sum);

    auto Largest = accumulate(intlst.cbegin(),intlst.cend(),0,[](int x, int y){ return x > y ? x : y;});
    print("largest",Largest);
    
//--------------------------------------------------------
    //foldl works from left inner parenthesis outwards
    string InStr = "MSFT";
    string k = "|";
    auto paren = foldl(InStr,k,
        [](auto IH, auto nextStep){
            string v = "(" + IH + nextStep + ")";
            return v;
            }
                );

    print("foldl",paren);
    //outputs ((((|M)S)F)T) for foldl
    //(((|M)S)F) is IH,   
    // T is nextStep


//--------------------------------------------------------

    auto parenR = foldr(InStr,k,
    [](auto IH, auto x){
        string v = "(" + IH + x + ")";
        return v;
        }
            );

    print("foldr",parenR);
    //outputs ((((|T)F)S)M) for foldr
    // can also be rewritten as (M(S(F(|T))))
    // (S(F(|T))) is IH
    // M is x
    // in haskell list x:xs, x operates on IH(xs).


    auto Reverse = foldr(InStr,k,
    //input MSFT
    [](auto IH, auto x){
        string v = IH + x ;
        //IH represents reverse(SFT)
        //x represents "M"
        return v;
        }
            );

    print("foldr reverse",Reverse);
    return 0;

}

3 Smart Pointers

In general, a function should take:

4 Rvalue Lvalue

5 Virtual functions

class Base
{
  public:
            void Method1 ()  {  std::cout << "Base::Method1" << std::endl;  }
    virtual void Method2 ()  {  std::cout << "Base::Method2" << std::endl;  }
};

class Derived : public Base
{
  public:
    void Method1 ()  {  std::cout << "Derived::Method1" << std::endl;  }
    void Method2 ()  {  std::cout << "Derived::Method2" << std::endl;  }
};

Base* basePtr = new Derived ();
  //  Note - constructed as Derived, but pointer stored as Base*

basePtr->Method1 ();  //  Prints "Base::Method1"
basePtr->Method2 ();  //  Prints "Derived::Method2"

6 Etc

int pp(){
    int g = 5;
    log(&g); //0x7ffeaa2e6d64
    return g;
}

int main(){
    int v; 
    log(&v); //0x7ffeaa2e6d8c
    v= pp();    
    log(&v); //0x7ffeaa2e6d8c
} 
int* pp(){
    int *p;
    int g = 5;
    p = &g;
    log("addr of g",p); // 0x7ffcebeead24
    assert(p == &g);
    log("value of g", g); // 5
    return p;
}

int main(){
    int* v; 
    v= pp();    
    log("addr of g:",v); //0x7ffcebeead24
    log("value of g", *v); // 0
}
//notice has the value of g is destroyed when assigning it to v.
int* pp(){
    int *p = new int(); //this lives outside the function on the HEAP until manually deleted
    *p = 5;
    log("addr of g",p); // 0x2079eb0
    log("value of g", *p); // 5
    return p;
}

int main(){
    int* v; 
    v= pp();    
    log("addr of g:",v); //0x2079eb0
    log("value of g", *v); // 5
    delete v; //this is where we delete the allocated *p
} 
int main(){
 
    int* v; //with a pointer we can dynamically allocate an array
    int cnt ;
    cin >> cnt;
    v = new int[cnt]; //like this
    for(int i = 0; i < cnt; i++){
        v[i] = i;
    }
    for(int i = 0; i < cnt; i++){
        log(i,v[i]);
    }
    delete v;
} 

6.1 arrays

  • 2d arrays cannot be built like this int v[2][2] = new int[2][2]
  • 2d arrays cannot be passed as arguments like void func(int stuff[][]) because the size is not specified

6.2 array as pointers

int main(){
// ptr ptr --*--> ptr --*--> val 
          

//init START
    int **v;
    
    int row;
    cin >> row;
    v = new int*[row];

    int col;
    cin >> col;
    for(int i = 0; i < col; i++){
        v[i] = new int[col];
    }
// init END

    for(int i = 0; i < row; i++){
        for(int j = 0; j< col; j++){
            v[i][j] = i*j;
        }
    }
    for(int i = 0; i < row; i++){
        for(int j = 0; j < col; j++){
            log(v[i][j]);
        }
    }
    delete v;
} 
  • Deref a = a[0]
  • A pointer is more powerful than an array
  • Anytime we have an array we can replace it with a pointer