using gcc by
gcc -lstdc++ -std=c+=17 -o exe sources...
preprocess by #include …
namespace
// namespaces.h
namespace mycode{
void foo();
}
// namespaces.cpp
namespace mycode{
void foo(){
}
}
- don’t use
using
at header file
// morenamespace.h
namespace Mylib{
namespace net{
namepsace ftp{
}
}
}
// is equal to
namespace Mylib::net::ftp{
}
// alias for namespace
namespace Myftp = Mylib::net:;ftp;
literal values
//
123 or 123'123'123 //数字分割符号
// oct
0173
// bin
0b1101
// hex 0x1f
// float
3.14f or 0.13'14f
// double
3.14
value cast
// recommend
int i1 = static_cast<int>(afloat);
int i1 = int(afloat);
int i1 = (int)afloat;
enum class
// enum with int
enum Pack{A=1,B,C=11,D}; // B=2 , D=12
// enum with class
enum class Pack{
A = 1,
B, // B is not 2
C = 10,
D // D is not 11
};//recommend
- [[fallthrough]]
func for this function name
int tellname(){
cout << __func__ <<endl;
return 0;
}
size of array
int arr[] = {1,2,3};
unsigned int size = std::size(arr);
// or
auto size = sizeof(arr)/sizeof(arr[0]);
array and vector
structure binding
- must use auto to bind values to a multistructure thing
initializer_list is like args
#include <initializer_list>
int makeSum(initializer_list<int> lst)
{
auto sum = 0;
for(auto &x: lst){
sum += x;
}
return sum;
}
c++ string
// 1. c type string is char[] or char*
// recommend using c++ type string
string hello = "hello world";
cout << hello << hello[1] << endl;
pointer and dynamic memory
// dynamic momory is for creating unknown size of data, it store to heap and let a stack pointer to point at that heap, notice that the pointer name is stand for stack memory address
// nulllptr and make some pointer that is new and let it be delete then using nullptr to reset it to momory 0, which is not a vaild place like
int newint = new int(10);
delete newint;
newint = nullptr;
// for array
int newarr = new int[10];
newarr[1] = 2;
delete[] newarr;
newarr = nullptr;
smart pointer
const usage
// always recommend pass a const & for a object and if it have to change, make it &
exception at
double div(double a, double b){
if (b==0)
throw invaild_argument(" b should not be 0");
return a / b;
}
try {
//if these code have some exceptions
cout << div(1,0) << endl;
}catch (const invaild_argument& exception){
cout << exception.what() << endl; // show b should not be 0
}
auto and decltype
decltype(foo()) f2 = foo();// tell me what the fuck type is foo()
define class
// usually declare A class at header file and source file to impl the class's method and static member(notice that static must be in global area)
// data member should have a m prefix, like m_var or mvar, that is a style of code
// if you don't want to change any data member value, make the member function const
// if you need to close file or release memory, make destructor explictly
// use class base on stack and heap
// recommend to use the init {}
raw string
- R"(hello: “world”)";
string literal
auto st1 = "hel";// const char *
using namespace std::string_literals;
auto st2 = "hel"s;// std::string
to_string(int|float|double...)
stoi(str);// string to int
stol(str,index,base); // string to long
to_chars(beginp,endp,base);// make int to char return beginp or errorcode
from_chars(strp,endstrp,int|float,format);
// string_view will not copy the string but return the const reference of the string
using namespace std::string_view_literals;
auto sv = "this is string view"sv;
// do not use c style string any more when starting a project
code style for project
// always write document for your code
// 1. explain the code's function when it must
// 2. must explain the public function: the target, the parameters, the return, and may be exceptions
/*
this method throw a "DatabaseNotOpenedException"
if the openDatabase() did not call before
Parameters:
Record& rd: the record to save to database
Returns: int
An int is id of saved record
Throws:
DatabaseNotOpenedException if openDatabase() not called
*/
int saveRecord(Record& rd);
// better
RecordID saveRecord(Record& record);
// if there is an algorithm ,must make comments
void sort(int inArray[],size_t inSize){
for(size_t i = 1;i < inSize;++i){
int element = inArray[i];
size_t j = i -1;
while(j > 0&&inArray[j]>element){
inArray[j+1] = inArray[j];
--j;
}
inArray[j+1] =element;
}
}// comment what code does
// meta info about author and date and filename and so on...
// use doxygen
// beter using variable name design to skip comment if it can
// a function is not more than 50 lines, if lines more than 50, put logical code to another function or try to reduce code
// write reusable code
// 1. make data field private and generate setter and getter when it must
// 2. make type more usual for sharing code
// 3. make big function extract to little function
// 4. pull up to base class or push down to derive class
// 5. don't use i or j as for loop counter
// 6. prefix or surfix to design private data field and static variable or static data member and constant value
// 7. make sure constanct value is at a namespace or enum class
// 8. use reference to replace pointer if it can
// 9. recommend self define exception
more professional software design
// before writing code, must design software
// 1. what datastruct it will use
// 2. what class it will have
// from the demand to analysis
// 1. write docs about what is going to realize instead of how to realize
// 2. use UML to design class: the above is data field and the below is method
// the principle of c++ design
// 1. must abstract
// 2. reusable
start a project of chess
- demand of chess
- sub system using UML graph
// many applications using MVC model to deal with data and views on data and there should have a interface about processing the data
// 1. data is called model, view is a special interface of model, controller is to change model and respone some events
// 2. actions is processing by controller and controller modify the model 动作交给控制器处理,控制器修改模型,把修改返回视图
- about sub system of chess game
// GamePlay
// ChessBoard
// ChessBoardView
// ChessPiece
// ChessPieceView
// Player
// ErrorLogger
- chessboard chesspiece is model
- chessboardview chesspieceview is view
- player is controller
- and view usually use observer design pattern to monitor the model
- player is using mediator
- errorlogger is using dependence injection
- about thread if it is needed
- UI thread
- audio thread
- net thread
- …
- it is recommended to avoid sharing data when it could be
now you should need to know what the fuck is software design it contains
- what actions
- how to do that action
- what view model controller
- how to combine view model controller
but what if you still are unaware what the fuck is software design just skip it and type code, it shows what the fuck that design have done
OOP design
is a
has a
not a
share a
better at abstraction
interface and pimpl idiom (私有实现习语)
nerver expose data field
reuse and abstract
for reuse: make code be a lib, design pattern
// when you see virtual void render() = 0; in a class, this is pure virtual function and it must be implement
// but what if virtual void render(){// do some} it shall be override
// in a word pure virtual decide virtual function,
class Shape{
public:
virtual void render() = 0;
};
class Square:public Shape{
public:
virtual void render() override {
// do render
}
};
class Circle:public Shape{
public:
virtual void render() override{
// do render for circle
}
};
class Renderer{
public:
void render(vector<share_ptr<Shape>> & objects);
};
void Renderer::render(vector<share_ptr<Shape>> & objects){
for(auto &obj:objects){
obj->render();
}
}
- SOLID principle
从开始到现在,到底学了什么?
1、一些c++17的语法,看前面语法部分,没有深入到每个细节
2、软件怎么设计,事实上,这部分知识几乎为0,这部分必须要实际开发才能体验得到,但是必须记住基本的概念,包含一部分常见设计模式,也就是说学了,好像又没有体会
now start a new subject
- about dynamic memory(其实这部分在objc体验得比较详细,
后期整理一下
)
out of box
- 西班牙语
1. Y 在西语相当于and,但是其后的第一个字母是元音的话,改为e
2. es 视作他或您,我不管男女,事物, eres 你