-
Notifications
You must be signed in to change notification settings - Fork 0
CPlusPlus
-
https://en.wikibooks.org/wiki/C%2B%2B_Programming/Code/Design_Patterns
-
http://www.boost.org/doc/libs/1_65_1/libs/graph/doc/index.html
-
https://www.codeproject.com/Articles/438922/Design-Patterns-of-Structural-Design-Patterns
std::list 👍 The add operation will instantiate a new MyClass, then copy in the data from the class instance that was to be added.
- https://www.doxygen.nl/manual/starting.html
- https://www.doxygen.nl/manual/doxywizard_usage.html
- https://www.stack.nl/~dimitri/doxygen/manual/autolink.html
- doxywizard
- ar - archiving; creates .a files
- Remove a .o file from a .a: ar d full.a something.o
- Add a .o to a .a: ar r full.a new.o
- c++filt - demangle c++ names
- doxygen - Generate the documentation, extracted from the source code.
- doxywizard - GUI for creating the doxygen.cfg
- gdb - debugger
- r - run
- c - continue (after attach)
- attach - attach to the process id: PID
- bt - backtrace
- nm - list symbol content
- for boost.so files you have to use '--dynamic'
- https://stackoverflow.com/questions/860339/difference-between-private-public-and-protected-inheritance
- https://www.tutorialspoint.com/cplusplus/cpp_inheritance.htm
- explicit: all parameters has to match in order for the function to be used?
- incline: TODO
m_listOfWalls.push_back(environmentWall);
std::list<EnvironmentWall*>::iterator it;
EnvironmentWall *pEnvironmentWall = nullptr;
for (it = m_listOfWalls.begin(); it != m_listOfWalls.end(); ++it)
{
pEnvironmentWall = (*it);
printf("DDD MapManager::renderEntities() startx: %d\n", pEnvironmentWall->getStartX());
SDL_RenderCopy(renderer, m_wallTexture, m_wallSourceRectangle, &destinationRectangle);
}
#include <map>
std::map<std::string, SpriteInfo*> m_mapNameToSprite;
Itterate:
for (STRING_MAP::const_iterator it = story_design_map.cbegin(); it != story_design_map.cend(); ++it)
{
send_dt(request, it->first);
send_dd(request, it->second);
}
- Extract and delete
STRING_PAIR returnPair;
STRING_MAP::iterator it;
returnPair.first = key;
returnPair.second = "";
it = story_design_map->find(key);
if (it != story_design_map->end())
{
returnPair.second = it->second;
story_design_map->erase(it);
}
std::string fileNameXml = "series.xml";
const char *const short_opts = "hi:";
const option long_opts[] = {
{"seriesfile", required_argument, nullptr, 'i'},
{"help", no_argument, nullptr, 'h'},
{nullptr, no_argument, nullptr, 0}};
int index;
int opt = 0;
while (opt != -1)
{
opt = getopt_long(argc, argv, short_opts, long_opts, &index);
switch (opt)
{
case 'i':
fileNameXml = optarg;
break;
}
}
- $@ - replaced with target.
- $< - The name of the first prerequisite.
- $? - The names of all the prerequisites that are newer than the target, with spaces between them.
- If the target does not exist, all prerequisites will be included.
- $^ - The names of all the prerequisites, with spaces between them.
# check code quality
.PHONY: cppcheck memcheck
cppcheck:
cppcheck --enable=all --language=c --std=c99 --inconclusive \
--suppress=missingInclude $(SRC) -i $(INCLDIR)
memcheck: all
valgrind -v --show-leak-kinds=all --leak-check=full --track-origins=yes \
./$(BIN)
#include <fstream>
std::ofstream cFile;
cFile.open("myfile.txt");
cFile << "Test text line" << std::endl;
cFile.close();
See: https://en.cppreference.com/w/cpp/filesystem/path
std::filesystem::path pathForSeriesFile{fileNameXml};
std::string directoryPathToSeriesFile = "./";
if (pathForSeriesFile.has_parent_path())
{
directoryPathToSeriesFile = pathForSeriesFile.parent_path().string();
}
std::cout << "DDD path: " << directoryPathToSeriesFile << std::endl;
- g++ -std=c++17 storystatus.cpp -o storystatus
#include <tinyxml2.h>
#include <string>
int main()
{
std::string fileNameXml = "series.xml";
tinyxml2::XMLDocument *xmlDoc = new tinyxml2::XMLDocument();
int nStatus = xmlDoc->LoadFile(fileNameXml.c_str());
if (nStatus == 0)
{
tinyxml2::XMLElement *xmlRoot = xmlDoc->RootElement();
}
}
- g++ storystatus.cpp -o storystatus -ltinyxml2
std::list<std::string> lDataList;
tinyxml2::XMLElement *xmlChildElement = NULL;
if (xmlElement != NULL) {
xmlChildElement = xmlElement->FirstChildElement(sTagName.c_str());
}
// From https://stackoverflow.com/questions/7942191/how-to-handle-tinyxml-null-pointer-returned-on-gettext
while (xmlChildElement != NULL) {
// This is here to make sure there is valid data in the child element
if (xmlChildElement->GetText() != NULL) {
lDataList.push_back(xmlChildElement->GetText());
} else {
lDataList.push_back("");
}
xmlChildElement = xmlChildElement->NextSiblingElement(sTagName.c_str());
}
return (lDataList);
See:
-
Src code: https://github.com/gafferongames/protocol2
-
Text: takes up too much bandwith at 60pkgs per second
-
Structure serialization:
- Endian conversion
- Can't transfer pointers
- Is a security risk if you just trust the package comming in on the network.
- You must, at minimum do some sort of per-field checking that values are in range vs. blindly accepting what is sent to you.
- This is why the memcpy struct approach is rarely used in professional games.
- You must, at minimum do some sort of per-field checking that values are in range vs. blindly accepting what is sent to you.
- https://stackoverflow.com/questions/6002528/c-serialization-techniques
- https://github.com/gafferongames/protocol2/blob/master/test.cpp
- https://gafferongames.com/post/reading_and_writing_packets/
- https://stackoverflow.com/questions/18310952/convert-strings-between-hex-format-and-binary-format
- http://www.cplusplus.com/forum/beginner/41657/
- https://codescracker.com/cpp/program/cpp-program-convert-hexadecimal-to-binary.htm
- https://www.reddit.com/r/shittyprogramming/comments/2sv2ow/had_to_convert_a_hex_char_to_binary_in_c_this_was/
- https://www.reddit.com/r/shittyprogramming/comments/2sv2ow/had_to_convert_a_hex_char_to_binary_in_c_this_was/cnt63dz/
- mkdir OUT_DIR
- protoc --cpp_out=OUT_DIR polyline.proto
See: https://github.com/zaphoyd/websocketpp/issues/631
WebSocket++ includes two major object types. The endpoint and the connection.
See: https://docs.websocketpp.org/md_tutorials_utility_client_utility_client.html
- creates and launches new connections
- maintains default settings for those connections.
- manage any shared network resources.
WebSocket++ endpoints are built by combining an endpoint role with an endpoint config.
There are two different types of endpoint roles,
- the client
- server roles in a WebSocket session.
Endpoint Config:
WebSocket++ endpoints have a group of settings that may be configured at compile time via the config template parameter.
- A config is a struct that contains types and static constants that are used to produce an endpoint with specific properties.
- Depending on which config is being used the endpoint will have different methods available and may have additional third party dependencies.
- Combine a config with an endpoint role to produce a fully configured endpoint. This type will be used frequently so I would recommend a typedef here.
typedef websocketpp::clientwebsocketpp::config::asio_client client
- stores information specific to each WebSocket session.
Once a connection is launched, there is no link between the endpoint and the connection.
- All default settings are copied into the new connection by the endpoint.
- Changing default settings on an endpoint will only affect future connections.
A new WebSocket connection is initiated via a three step process.
- a connection request is created by endpoint::get_connection(uri).
- the connection request is configured.
- the connection request is submitted back to the endpoint via endpoint::connect() which adds it to the queue of new connections to make.
WARNING: A connection_ptr allows direct access to information about the connection and allows changing connection settings. Because of this direct access and their internal resource management role within the library it is not safe for end applications to use connection_ptr except in the specific circumstances. See: https://docs.websocketpp.org/md_tutorials_utility_client_utility_client.html
See:
- https://docs.websocketpp.org/md_tutorials_utility_client_utility_client.html
- https://docs.websocketpp.org/reference_8handlers.html
Handlers can be registered at the endpoint level and at the connection level. Endpoint handlers are copied into new connections as they are created.
- REGEX - How to match and search any pattern or validate input? (Regular expressions 30-min course)
- RegExStorm
Special:
- . - any char
- [] -
- ? - 0 or 1
-
-
- one or more
-
-
-
- 0 or more
-
- {} - match exactly this amount of times
- \w - maybe works [a-zA-Z0-9]+
#include <string>
#include <regex>
std::string regexPattern = "\\w+\\.\\w+@\\w+\\.com";
std::regex regexRule(regexPattern);
std::string testString = "saldina@gmail.com";
bool isValidEmail = regex_match(testString, regexRule);
// Paretnthises must be in to be able to combine multiple rules
std::string lowercasePattern = "(?=.*[a-z])"
std::string uppercasePattern = "(?=.*[A-Z])"
std::string numberscasePattern = "(?=.*[0-9])"
std::string specialCharactersPattern = "(?=.*[$_@])"
std::string minCharactersn = "(?=.{6,})"
std:string fullPattern = lowercasePattern + uppercasePattern + numberscasePattern + specialCharactersPattern + minCharactersn;
std::string testStringPassword = "V3ryS3cret_";
std::regex regexPasswordRule(fullPattern);
// Use search because it is a number of rules combined, and not a single pattern.
bool isValidPassword = regex_search(testStringPassword, regexRule);
// see: https://www.youtube.com/watch?v=IOxKjqC1Ozo
#include <regex>
#include <iostream>
void dump_regex_matches(const std::cmatch &match)
{
std::cout << "Matches:" << std::endl;
for (std::size_t index = 0; index < match.size(); ++index)
{
std::cout << index << ": " << match.str(index) << std::endl;
}
}
int main()
{
// the '[^\]' means everything up until the closing square bracket.
std::regex regex_pattern(R"((\d+): \[([^\]]+)\] (.*))");
std::string testString = "123: [error] Hello World";
std::cmatch match;
std::regex_match(testString.c_str(), match, regex_pattern);
dump_regex_matches(match);
}
Output:
Matches:
0: 123: [error] Hello World
1: 123
2: error
3: Hello World
-
https://docs.microsoft.com/en-us/cpp/cpp/lambda-expressions-in-cpp?view=vs-2019
- Good/thorough explanation
-
the lambda expression is actually a class.
-
In order to call it, the compiler needs to instantiate an object of the class.
-
The object instantiated from a lambda expression is called a lambda closure.
- [ captures ] ( params ) specifiers exception attr -> ret requires { body }
- captures: aka lambda-introducer. makes sourounding vars available inside the body, either as references or value. From C++14 captures and also introduce new variables.
- '&varname' by reference.
- 'varname' by value.
- '&' alone means default is to reference all non mentioned vars as reference.
- '=' default get all by value.
- Only variables that are mentioned in the lambda are captured when a capture-default is used.
- If a capture clause includes a capture-default &, then no identifier in a capture of that capture clause can have the form & identifier.
- Likewise, if the capture clause includes a capture-default =, then no capture of that capture clause can have the form = identifier.
- An identifier or this cannot appear more than once in a capture clause.
- A capture followed by an ellipsis is a pack expansion
- captures: aka lambda-introducer. makes sourounding vars available inside the body, either as references or value. From C++14 captures and also introduce new variables.
- params: A parameter list (lambda declarator in the Standard syntax) is optional and in most aspects resembles the parameter list for a function(MS).
- specifiers: mutable specification Optional.
- The mutable specification enables the body of a lambda expression to modify variables that are captured by value.
- if n is param(copy by value). The mutable specification allows n to be modified within the lambda.
- exception: optional 'throw()'
- You can use the noexcept exception specification to indicate that the lambda expression does not throw any exceptions.
- attr: ?
- -> ret: trailing-return-type Optional. define the return type, can be auto.
- The return type of a lambda expression is automatically deduced. You don't have to use the auto keyword unless you specify a trailing-return-type.
- requires: ?
- body:
- The body of both an ordinary function and a lambda expression can access these kinds of variables:
- Captured variables from the enclosing scope, as described previously.
- Parameters
- Locally-declared variables
- Class data members, when declared inside a class and this is captured
- Any variable that has static storage duration—for example, global variables
- The body of both an ordinary function and a lambda expression can access these kinds of variables:
These are my personal takes on 'auto'
- Use auto for throw away things, like iterators.
- Where it is a derived thing.
- Do not use auto for primary definitions, it makes it harder for newcomers to read the code
- This is a compiler abstraction.
- When you invoke a template with a specific type the compiler creates a specialization of the template with that specific type.
- Basically the compilers writes the templated code with the typenames replaced, e.g. replace 'T' with 'int'.
- Using templates incur overhead both at compile time and run time.
- Template classes er generally entirely defined in header files.
- You can't have the definition and implementation of templates in separate .h and .cpp files, the linker wont be able to link them correctly.
See: 'C++ Templates and the STL' in LinkedIn learning.
- use 'typename' or 'class' to define the 'TYPE' thingy
- template
- template T>
- 'T' is an alias
https://stackoverflow.com/questions/1057287/ofstream-error-in-c
Use: #include
Possibly missing protobuf-c or protobuf-dev