[toc]
C++ Solution and Project
Solution is a vessel containing projects, and the code is the actual organizational unit of the project.
Solution is used to organize and manage multiple projects, while a project is used for real operations and construction.
hello_world 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include <iostream> #if 1 static void log () { std::cout << "hello World" << std::endl; } int main () { std::cout << "hello World" << std::endl; std::cin.get (); return 0 ; } #endif
cin、cout
,Corresponding to the standard input stream and the standard output stream
std::cout << "hello World" << std::endl;
can be considered asstd::cout.print("hello world").print("\n");
variable
The sizeof()
function returns the size of variables.
If we define a float, we must add ‘f’ behind the variable, such as 0.3f. Otherwise, it will be recognized as a double variable.
head file 0x0 The difference between ""
and <<>>
:
Angle brackets are only used by the compiler to include paths. Quotes can do anything, but they are usually used for relative paths.
We have two ways to ensure that a header file is included only once:
0x1 #pragma once
means only include this header file once.
0x2 1 2 3 4 #ifndef FunctionA #define FunctionA void FunctionA () ; #endif
* and &
A Reference Is an Alias.
A reference is not an object. Instead, a reference is just another name for an already existing object.
A reference must be initialized.
1 2 3 4 5 6 7 8 9 10 void Function (int & value) { value ++; } int main () { int a = 10 ; Function (a); }
static
Use the prefix s_
to denote a static variable
static functions and global variables are accessible only from within the translation unit.
A static local variable persists after the function exits.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #include <iostream> void Function () { static int i = 0 ; i++; std::cout << i << std::endl; } int main () { Function (); Function (); Function (); Function (); Function (); std::cin.get (); }
A static class variable or method can have only one instance.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #include <iostream> struct Entity { static int x, y; static void Print () { std::cout << x << ", " << y << std::endl; } }; int Entity::x;int Entity::y;int main () { Entity e; Entity::x = 2 ; Entity::y = 3 ; Entity e1; Entity::x = 5 ; Entity::y = 8 ; Entity::Print (); Entity::Print (); }
Requires the variable to survive the function exit: Use static to decorate a local variable.
You need to scope the variable to the current file: static decorates a global variable.
Member variables/functions need to be called in case of shared variables or functions: static modifies member variables/functions.
extern
extern can be used to decorate a variable or function when you need to import a non-static variable or function from an external file.
-> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <iostream> #include <string> struct Vector3 { double x, y, z; }; int main () { int offset = (int )&((Vector3*)0 )->z; std::cout << offset << std::endl; offset = (int )&((Vector3*)1000 )->z; std::cout << offset << std::endl; std::cin.get (); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 #include <iostream> #include <string> class Entity { private : int x; public : void Print () const { std::cout << "hello" << std::endl; } }; class ScopedPtr { private : Entity* m_obj; public : ScopedPtr (Entity* entity) :m_obj (entity) { } ~ScopedPtr () { delete m_obj; } Entity* operator ->() { return m_obj; } const Entity* operator ->() const { return m_obj; } }; int main () { ScopedPtr e = new Entity; e->Print (); std::cin.get (); }
union 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 #include <iostream> #define print(x,y) std::cout<< x << ": " << y << std::endl struct vector2 { int a, b; }; struct vector4 { union { struct { int a, b, c, d; }; struct { vector2 A, B; }; }; }; int main () { vector4 vector{1 ,2 ,3 ,4 }; print ("vector.A.a" , vector.A.a); print ("vector.b" , vector.A.b); print ("vector.B.a" , vector.B.a); print ("vector.d" , vector.d); std::cin.get (); }
enum 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <iostream> enum Example : unsigned char { A = 5 , B, C }; int main () { Example value = B; if (value == 6 ) { std::cout << "hello" << std::endl; } std::cin.get (); }
linking static linking && dynamic linking
1 2 3 4 5 6 7 8 9 10 #include <iostream> extern "C" int glfwInit () ;int main () { int a = glfwInit (); std::cout << a<< std::endl; }
使用 __declspec(dllimport) 导入到应用程序中 |Microsoft学习
//TODO
lib //TODO
return //TODO
macro
Can be used to manage release and Debug versions
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include <iostream> #include <string> #ifdef PR_DEBUG #define Edition() std::cout << "Debug" << std::endl #elif defined(PR_RELEASE) #define Edition() std::cout << "Release" << std::endl #endif #if 0 function (); #endif #define MAIN int main() { \ Edition(); \ std::cin.get(); \ } MAIN
auto 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #include <iostream> #include <vector> #include <string> #include <unordered_map> class Device {};class DevieManager { private : std::unordered_map<std::string, std::vector<Device*>> m_Devices; public : const std::unordered_map<std::string, std::vector<Device*>>& GetDevices () const { return m_Devices; } }; int main () { std::vector<std::string> strings; strings.push_back ("Randolfluo" ); strings.push_back ("114514" ); for (auto it = strings.begin (); it != strings.end (); it++) { std::cout << *it << std::endl; } DevieManager dm; const auto & devices = dm.GetDevices (); std::cin.get (); }
function pointer 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <iostream> #include <vector> void Print (int x) { std::cout << x << std::endl; } void forEach (const std::vector<int >& values, void (*func)(int )) { for (int value : values) func (value); } int main () { std::vector<int > values = { 1 ,2 ,3 ,4 ,5 }; forEach(values, Print); auto fun = Print; fun (114514 ); std::cin.get (); }
lambda
namespace
Namespaces can be used as additional information to distinguish functions, classes, variables, and so on with the same name from different libraries.
Use it in the smallest scope possible.
Make sure there are no conflicts with other namespaces
Never use in header files
multidimensional array 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 #include <iostream> #include <chrono> #include <thread> const int N = 30000 ;class Timer {private : const char * m_Name; public : std::chrono::time_point < std::chrono::steady_clock> start,end; std::chrono::duration<float > duration ; Timer () :m_Name ("Unknown" ) { start = std::chrono::high_resolution_clock::now (); } Timer (const char * name) :m_Name (name) { start = std::chrono::high_resolution_clock::now (); } ~Timer () { end = std::chrono::high_resolution_clock::now (); duration = end - start; auto duration1 = std::chrono::duration_cast <std::chrono::milliseconds>(end - start); std::cout << m_Name<< ":" << duration1 << std::endl; } }; void array2d_1 () { Timer time ("array2d_1" ) ; int ** a2d = new int * [N]; for (int i = 0 ; i < N; i++) a2d[i] = new int [N]; for (int i = 0 ; i < N; i++) for (int j = 0 ; j < N; j++) a2d[i][j] = 123 ; for (int i = 0 ; i < N; i++) delete [] a2d[i]; delete [] a2d; } void array2d_2 () { Timer time ("array2d_2" ) ; int * array = new int [N * N]; for (int i = 0 ; i < N; i++) for (int j = 0 ; j < N; j++) array[i*N+j] = 123 ; delete [] array; } int main () { array2d_1 (); array2d_2 (); std::cin.get (); }
type cast
static_cast
reinterpre_cast
dynamic_cast (Runtime type information)
const_cast
dynamic_cast
is specialized for pointer casting in inheritance hierarchies and must be a polymorphic class type (base class has vtable)
//TODO
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include <iostream> #include <string> class Entity { public : virtual void Print () {}; }; class Player : public Entity{ }; class Enemy : public Entity{ }; int main () { Player* player = new Player (); Entity* actuallyEnemy = new Enemy (); Player* actuallyPlayer = player; Player* p0 = dynamic_cast <Player*>(actuallyEnemy); Player* p1 = dynamic_cast <Player*>(actuallyPlayer); }
explicit \\TODO
templetes(generics)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <iostream> #include <string> template <typename T>void Print (T value) { std::cout << value << std::endl; } template <typename T, int N>class Array { private : T m_Array[N]; public : int GetSize () const { return N; } }; int main () { Array<int , 5 > array; std::cout << array.GetSize () << std::endl; Print (123 ); Print ("Randolfluo" ); std::cin.get (); }
Smart ptr 我们不能复制unique_ptr,因为free掉回产生空指针问题
unique_ptr
Unique_ptr deletes when over the scope.
We can’t copy unique_ptr,because when class free will generate null pointer.
shared_ptr
When the reference count equals zero, destruct the entity.
weak_ptr
weak_ptr can’t make reference count increase or decrease.
A weak_ptr cannot increase or decrease the reference count.
auto_ptr
(deprecated in C++11) (removed in C++17)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #include <iostream> #include <string> #include <memory> class Entity { private : int m_Num; public : Entity (int x) :m_Num (x) { std::cout << "call Entity " << m_Num << std::endl; } ~Entity () { std::cout << "destruct Entity " << m_Num << std::endl; } }; int main () { { std::shared_ptr<Entity> e0; { std::unique_ptr<Entity> entity = std::make_unique <Entity>(1 ); std::shared_ptr<Entity> sharedEntity = std::make_shared <Entity>(2 ); e0 = sharedEntity; } } std::cin.get (); }