More code Flashcards
(22 cards)
Templates
Templates is a feature that allows classes and objects to operate with generic types. You can choose what kind of types will be used for any method and data member by offering those types as arguments into a template directly over the class or object.
template class test { public: T getData() { return m_data; } private: T m_data; };
int main() { test classWithInts; system("PAUSE"); return 0; }
Aliasing
Type Defs (Definitions) and Using keywords
Aliasing is when you assign a handle to a data type so you can have simpler names for certain long data types.
Using is the keyword you want to use for this. But using and typedef do the same thing.
Aliasing is not only used for less typing however, it can also be used for pseudo templating by using the alias name in a bunch of places and then easily changing it in one place will change it for all of those places.
using test = std::vector;
typedef std::vector test2;
int main() {
test myVec; // using test2 myVec; // typedef'd system("PAUSE"); return 0; }
What is Chrono?
What is it used for?
How do you access Chrono?
include
Chrono is a standard namespace tool that allows the user access to a plethera of time oriented tools.
For our purposes it will usually be used for capturing delta time using the “stopwatch” methods.
// OR auto start = ... std::chrono::time_point start = std::chrono::high_resolution_clock::now(); // get the start time
// Do some shit int test = 0; for (int i = 0; i < 100000; ++i) { test += i * 5 + rand() % 1000; }
// OR auto end = ... std::chrono::time_point end = std::chrono::high_resolution_clock::now(); // get the ending time
std::chrono::duration duration = end - start; // Delta
// should probably be "long long", or just auto for convenience. auto ms = std::chrono::duration_cast(duration).count(); // Convert to ms
std: :cout << ms << "ms " << std::endl; // milliseconds std: :cout << duration.count() << "s " << std::endl; // seconds
What is Exception Handling?
How does it work(pseudo-code)?
Proactively handling program threatening errors and/or undesired behavior before certain code runs.
You enter conditional throws.
You then “try” (which is a keyword) a step of code
Then you set up catch statements that follow the same syntax as else if.
struct myException { myException(int l_x, const std::string& l_why) : x(l_x), why(l_why) {} int x; std::string why; };
int divide(int x, int y) { if (y == 0) { throw myException(5, "Division by zero"); } return x / y; }
int main() { try { int test = divide(5, 0); } catch (const char* msg) { std::cout << "Error!" << std::endl; std::cout << msg << std::endl; } catch (myException& exc) { std::cout << exc.x << " " << exc.why << std::endl; } system("PAUSE"); return 0; }
Range-based for loops
A for loop that WILL iterate through an stl container.
std::vector myVector; myVector.push_back(1); myVector.push_back(2); myVector.push_back(3); for (auto& myElement : myVector) { std::cout << myElement << std::endl; }
Iterators
Special class included with the container you are using to iterate through containers with better functionality, versatility and safety. Essentially whenever your iterating through a container and need to modify the element structure in the container.
std::vector myVector; myVector.push_back(1); myVector.push_back(2); myVector.push_back(3); for (std::vector::iterator itr = myVector.begin(); itr != myVector.end(); ++itr) { std::cout << *itr << std::endl; }
Unordered Maps (Python Dictionary)
Dictionaries with key value pairs, the key can be any data type and the element can be any data type.
The key should be easily hashable which means strings and integers work best.
std::unordered_map myMap;
myMap.emplace("test", shit(1, 2, 3, 4)); myMap.insert(std::make_pair("test2", shit(1, 2, 3, 4))); auto v = myMap["test"]; for (auto& itr : myMap) { itr.first; auto& actualShit = itr.second; }
Argument Evaluation Orders
and what does this to us?
PEMDAS
AEO’s will change depending on Operating System Compiler, time of day. Versions of each
Because of this whenever we plan to write argument evaluations for different platforms it’s best to be as concise as possible using parenthesis and no doing anything overly complicated with operators which falls in line with code readability and KISS.
Override Keyword
Override is a specifier keyword you place to the right of the signature, before the definition, of any virtual method you plan to override, it shows intent and checks you on the spot in most IDEs
class base { public: virtual void test() {} };
class derived : public base { public: virtual void test() override {} };
class anotherDerived : public derived { void test() override {} };
Final Keyword
Final is a specifier keyword you place to the right of the signature, before the definition, of any virtual method you plan to override, it shows intent and checks you on the spot in most IDEs —– AND
It makes it the “final” override meaning it can not be overridden.
class base { public: virtual void test() {} };
class derived : public base { public: virtual void test() override final {} };
class anotherDerived : public derived { void test() override {} };
Constexpr Keyword
Constexpr is used to make a value or an operation known at compile time. It does imply const but does more and should not be used interchangeably.
constexpr int multiply(int a, int b) {
return a * b;
}
constexpr int t = 55; // it does imply “const”, but does more
Noexcept Keyword
Noexcept is a specifier keyword you place to the right of the signature, before the definition, to tell the compiler that there will be no exceptions in this portion of your code, or if there is, to ignore them. It is used for optimization.
Pre-processor Directives and Macros
Macros are statements that get evaluated and executed at compile time.
————#define
#define DOTHING(a, b) add(a, b) #define ISGREATER(a, b) (a > b ? true : false)
int multiply(int a, int b) { return a * b; }
int add(int a, int b) { return a + b; }
int main() { int test = DOTHING(5, 6); bool what = ISGREATER(1, 2);
std::cout << test << std::endl; system("PAUSE"); return 0; }
Type Punning
Getting around the type system with any kind of casting, implicit or explicit.
Here is a simple example of type punning. An implicit conversion of an int to a double:
int main() { int a = 50; double value = a;
std::cin.get(); }
In memory the int is different from the double because of the way conversions are done internally in c++.
An explicit conversion here would be written like this:
double value = (double)a;
This is more explicit.
If you wanted to treat a struct with ONLY simple primitive data types in it you could do so by casting that instance of that struct to a int* and assigning that to your handle int* like so:
Entity e= { 5 , 8 };
int* position = (int*)&e;
This will treat it as an c style array.
Read this.
What will print?
struct Entity
{
int x, y;
};
int main() { Entity e = { 5 , 8 };
int* position = (int*)&e; int y = *(int*)((char*)&e + 4); std::cout << y << std::endl;
std::cin.get();
}
8
Static Cast
A precision cast that will do compile time checking for you to make sure they share 1 level inheritance
Dynamic Cast
A precision cast that will do run time checking for you to make sure they share inheritance. Will return null if it’s not in the inheritance tree which you can run checks on easily.
Reinterpret Cast
Lets you do whatever you want. Danger
C++ Casts
What are they?
Static Cast
Dynamic Cast
Reinterpret Cast
and Const Cast
C++ style casts offer no extra functionality outside of a few of them running checks at compile time for static and at run time for dynamic. Not all of them do but it allows to show intent and it’s more precise.
Sorting
Read this,
What will this print?
int main() { std::vector values = { 3, 5, 1, 4, 2 }; std::sort(values.begin(), values.end(), [](int a, int b) { if (a == 1) return false; if (b == 1)
return a > b; }); for (int value : values) std::cout << value << std::endl;
2 3 4 5 1
Threads
Fuck off