C++: Difference between revisions
Line 63: | Line 63: | ||
} | } | ||
return 0; | return 0; | ||
} | |||
</syntaxhighlight> | |||
====Reading a whole file==== | |||
[https://insanecoding.blogspot.com/2011/11/how-to-read-in-file-in-c.html Reference and comparison of different methods] | |||
<syntaxhighlight lang="C++"> | |||
#include <fstream> | |||
#include <string> | |||
#include <cerrno> | |||
std::string get_file_contents(const char *filename) | |||
{ | |||
std::ifstream in(filename, std::ios::in | std::ios::binary); | |||
if (in) | |||
{ | |||
std::string contents; | |||
in.seekg(0, std::ios::end); | |||
contents.resize(in.tellg()); | |||
in.seekg(0, std::ios::beg); | |||
in.read(&contents[0], contents.size()); | |||
in.close(); | |||
return(contents); | |||
} | |||
throw(errno); | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> |
Revision as of 18:58, 23 October 2019
Usage
How to do things using the C++ standard library (stdlib).
Compilation
g++
g++ my_driver.c [-Iincludefolder] -o my_program.out
Misc optimizations
-std=c++17
for C++17 support-O3
for level 3 optmizations
Syntax
Lambda Expressions
Arrays
In C++, you can use std::vector
which gives you a resizable array.
This will allocate an array in the heap.
array vs vector
If you need a static sized array, you can use std::array
.
This wrapper around C-style arrays gives us size information and allows the array to be passed around while keeping the array on the stack unlike std::vector
If you want to allocate a static array on the heap, you can do so as follows:
auto my_arr = std::make_shared<std::array<char,64>>();
Strings
String Interpolation
#include <iostream>
#include <sstream>
#include <string>
int main() {
std::string a = "a", b = "b", c = "c";
// apply formatting
std::stringstream s;
s << a << " " << b << " > " << c;
// assign to std::string
std::string str = s.str();
std::cout << str << "\n";
}
Filesystem
Reading and Writing
Reading and writing is done using fstream
.
If you don't need r/w, use istream
for reading or ostream
for writing.
#include <iostream>
#include <fstream>
int main() {
std::istream my_file("my_file.txt");
std::string line;
# Read line by line
# You can also read using <<
while (getline(my_file, line)) {
std::cout << line << std::endl;
}
return 0;
}
Reading a whole file
Reference and comparison of different methods
#include <fstream>
#include <string>
#include <cerrno>
std::string get_file_contents(const char *filename)
{
std::ifstream in(filename, std::ios::in | std::ios::binary);
if (in)
{
std::string contents;
in.seekg(0, std::ios::end);
contents.resize(in.tellg());
in.seekg(0, std::ios::beg);
in.read(&contents[0], contents.size());
in.close();
return(contents);
}
throw(errno);
}
Regular Expressions
Thread
Sleep
std::this_thread::sleep_for(std::chrono::milliseconds(1));
Parallel For
Memory
Smart Pointers
Smart Pointers
Smart pointers were added in C++11.
There are 4 types of smart pointers:
auto_ptr
which is deprecatedunique_ptr
shared_ptr
weak_ptr
Use unique_ptr
for ownership models.
Use shared_ptr
when multiple objects need to reference the same thing.
Use weak_ptr
to avoid cyclic dependencies which cause issues with reference counting.
Example:
std::unique_ptr<Car> my_car(new Car());
// Or starting from C++14
auto my_car = std::make_unique<Car>();
Garbage Collection
Starting from C++11, you should use smart pointers such as shared_ptr
which have automatic garbage collection.
Traditional C++ does not have garbage collection.
After using new
to allocate an object, use delete
to deallocate it.
You can also use C allocation with malloc
, calloc
, alloca
, and free
, though it is not recommended since these are not type-safe.
Custom Deleter
Custom Deleters
When using smart pointers, the default deleter is the delete
function but you can also specify your own deleter.
# Using a functor
struct AVFrameDeleter {
void operator()(AVFrame *p) { av_frame_free(&p); }
};
std::unique_ptr<AVFrame, AVFrameDeleter> rgb_frame(av_frame_alloc());
# Using free
std::unique_ptr<void *, decltype(std::free) *> my_buffer(std::malloc(10), std::free);
Deallocate
Normally, containers such as std::vector
will automatically deallocate memory from the heap when the destructor is called. However, occationally you may want to coerse this deallocation yourself.
There are a few ways to do this:
- Use smart pointers
- Copy-and-swap idiom
- Call a clear/shrink/deallocate function
Example Reference:
// Using smart pointers
std::unique_ptr<std::vector<float>> my_vector = make_unique<std::vector<float>>(99);
my_vector.reset();
// Copy-and-swap idiom
std::vector<float> my_vector(99);
std::vector<int>().swap(my_vector);
// Clear and shrink
// Specific to std::vector
std::vector<float> my_vector(99);
my_vector.clear();
my_vector.shrink_to_fit();
Casting
Types of casts C++ has several types of casts. These are the main ones you should use.
static_cast
dynamic_cast
If you're casting between things but do not want to change the bit-pattern (e.g. binary data or pointers), you can also use reinterpret_cast
.
Programming Styles
Modern C++
List of resources
Prefer newer std functions available in C++17.
Use shared pointers instead of new and delete.
- Use clang-format.
Orthodox C++
Reference
Somewhat opposite of modern C++.
Basically only use C++ for its classes. Do everything else C-style.
The main benefit is compatibility with older compilers/libraries and easier understanding for people less familiar with newer C++ features.
- Don't use C++ runtime wrapper for C runtime includes (<cstdio>, <cmath>, etc.), use C runtime instead (<stdio.h>, <math.h>, etc.)
- Don't use stream (<iostream>, <stringstream>, etc.), use printf style functions instead.
- Don't use anything from STL that allocates memory, unless you don't care about memory management.