Jump to content

C++: Difference between revisions

7,174 bytes added ,  26 November 2019
no edit summary
No edit summary
(43 intermediate revisions by the same user not shown)
Line 1: Line 1:
__FORCETOC__
__FORCETOC__
C++ is a very popular and powerful language which includes all the low-level features of [[C_(programming_language) | C]] (e.g. pointers, operator overloading) along many high-level features (regex, STL containers) thanks to the C++ standard library.<br>
Some people may think of it as an object-oriented version of C.


==Usage==
==Usage==
How to do things using the [https://en.wikipedia.org/wiki/C%2B%2B_Standard_Library C++ standard library (stdlib)].
How to do things using the [https://en.wikipedia.org/wiki/C%2B%2B_Standard_Library C++ standard library (stdlib)].
===Compilation===
===Compilation===
{{See also|CMake|Makefile}}
====g++====
====g++====
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
Line 11: Line 14:
* <code>-std=c++17</code> for C++17 support
* <code>-std=c++17</code> for C++17 support
* <code>-O3</code> for level 3 optmizations
* <code>-O3</code> for level 3 optmizations
===Strings===
 
===Syntax===
====Main====
All C++ programs launch in a <code>main</code> function.
Similar to [[C]], the arguments are <code>int argc</code> and <code>char *argv[]</code>.
These can be easily converted to a <code>std::vector<std::string></code> for convenience.
<syntaxhighlight lang="cpp">
#include <string>
#include <vector>
int main(int argc, char *argv[]) {
  std::vector<std::string> args(argv, argv + argc);
  // Your code here
  return EXIT_SUCCESS;
}
</syntaxhighlight>
 
====Headers====
[https://stackoverflow.com/questions/10694255/cmath-vs-math-h-and-similar-c-prefixed-vs-h-extension-headers Reference]
C++ includes C-headers such as <code>math.h</code> and <code>cmath</code>.<br>
The C-style header will place everything in the global namespace while the C++ header will place everything in <code>std</code>.<br>
You should use <code>cmath</code>.
 
====Lambda Expressions====
[https://en.cppreference.com/w/cpp/language/lambda Reference]
 
====Casting====
[https://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-const-cast-and-reinterpret-cast-be-used Types of casts]
C++ has several types of casts.
These are the main ones you should use.
* <code>static_cast</code>
* <code>dynamic_cast</code>
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 <code>reinterpret_cast</code>.
 
===Array===
<code>#include <array></code><br>
In C++, you can use <code>std::vector</code> which gives you a resizable array.
This will allocate an array in the heap.<br>
 
[https://shendrick.net/Coding%20Tips/2015/03/15/cpparrayvsvector.html array vs vector]<br>
If you need a static sized array, you can use <code>std::array</code> in the <code>array</code> header.<br>
This wrapper around C-style arrays gives us size information and allows the array to be passed around by reference while keeping the array on the stack unlike <code>std::vector</code>.<br>
If you want to allocate a static array on the heap, you can do so as follows:
<syntaxhighlight lang="C++">
auto my_arr = std::make_shared<std::array<char,64>>();
</syntaxhighlight>
 
===String===
<code>#include <string></code><br>
====String Interpolation====
====String Interpolation====
[https://stackoverflow.com/questions/10410023/string-format-alternative-in-c Reference]
[https://stackoverflow.com/questions/10410023/string-format-alternative-in-c Reference]
Line 30: Line 80:
</syntaxhighlight>
</syntaxhighlight>
===Filesystem===
===Filesystem===
<code>#include <fstream></code><br>
====Reading and Writing====
====Reading and Writing====
Reading and writing is done using <code>fstream</code>.<br>
Reading and writing is done using <code>fstream</code>.<br>
Line 46: Line 97:
   }
   }
   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(std::string 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());
    return contents;
  }
  throw(errno);
}
}
</syntaxhighlight>
</syntaxhighlight>


===Regular Expressions===
===Regular Expressions===
<code>#include <regex></code><br>
[https://en.cppreference.com/w/cpp/regex Reference]
[https://en.cppreference.com/w/cpp/regex Reference]
<!--
<!--
Line 63: Line 138:
-->
-->


===Threading===
===Thread===
<code>#include <thread></code><br>
==== Sleep ====
==== Sleep ====
<syntaxhighlight lang="C++">
<syntaxhighlight lang="C++">
std::this_thread::sleep_for(std::chrono::milliseconds(1));
std::this_thread::sleep_for(std::chrono::milliseconds(1));
</syntaxhighlight >
</syntaxhighlight >
====Parallel For====
[https://www.alecjacobson.com/weblog/?p=4544 Reference]


===Memory===
===Memory===
<code>#include <memory></code><br>
====Smart Pointers====
====Smart Pointers====
[https://www.geeksforgeeks.org/auto_ptr-unique_ptr-shared_ptr-weak_ptr-2/ Smart Pointers]<br>
[https://www.geeksforgeeks.org/auto_ptr-unique_ptr-shared_ptr-weak_ptr-2/ Smart Pointers]<br>
There are 4 types of smart pointers
Smart pointers were added in C++11.<br>
There are 4 types of smart pointers:
* <code>auto_ptr</code> which is [https://stackoverflow.com/questions/3697686/why-is-auto-ptr-being-deprecated deprecated]
* <code>auto_ptr</code> which is [https://stackoverflow.com/questions/3697686/why-is-auto-ptr-being-deprecated deprecated]
* <code>unique_ptr</code>
* <code>unique_ptr</code>
Line 80: Line 160:
Use <code>shared_ptr</code> when multiple objects need to reference the same thing.<br>
Use <code>shared_ptr</code> when multiple objects need to reference the same thing.<br>
Use <code>weak_ptr</code> to avoid cyclic dependencies which cause issues with reference counting.<br>
Use <code>weak_ptr</code> to avoid cyclic dependencies which cause issues with reference counting.<br>
If you are using C++14 or newer, you should use <code>make_unique</code> or <code>make_shared</code> which will only make one memory allocation for both the object and the pointer rather than two memory allocations.<br>
Alternatively if you already have a smart pointer, you can call <code>my_ptr.reset(new Car())</code> to change the pointer or <code>my_ptr.reset()</code> to deallocate the object referenced by the pointer.
Example:
<syntaxhighlight lang="cpp">
// Block-scope car
Car my_car;
// Old C++
// Must call delete my_car; to avoid memory leaks.
Car *my_car = new Car();
// Using unique ptr
std::unique_ptr<Car> my_car(new Car());
// Or starting from C++14
auto my_car = std::make_unique<Car>();
</syntaxhighlight>
Note: If the object you need is not very large, you can consider just including it as part of your class (or leaving it on the stack) rather than use pointers.


====Garbage Collection====
====Garbage Collection====
Starting from C++14, you should use smart pointers such as [https://en.cppreference.com/w/cpp/memory/shared_ptr <code>shared_ptr</code>] which have automatic garbage collection.<br>
Starting from C++11, you should use smart pointers such as [https://en.cppreference.com/w/cpp/memory/shared_ptr <code>shared_ptr</code>] which have automatic garbage collection.<br>
<br>
<br>
Traditional C++ does not have garbage collection.<br>
Traditional C++ does not have garbage collection.<br>
Line 88: Line 186:
You can also use C allocation with <code>malloc</code>, <code>calloc</code>, <code>alloca</code>, and <code>free</code>, though it is [https://stackoverflow.com/questions/184537/in-what-cases-do-i-use-malloc-and-or-new not recommended] since these are not type-safe.<br>
You can also use C allocation with <code>malloc</code>, <code>calloc</code>, <code>alloca</code>, and <code>free</code>, though it is [https://stackoverflow.com/questions/184537/in-what-cases-do-i-use-malloc-and-or-new not recommended] since these are not type-safe.<br>


===Casting===
====Custom Deleter====
[https://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-const-cast-and-reinterpret-cast-be-used Types of casts]
[https://www.bfilipek.com/2016/04/custom-deleters-for-c-smart-pointers.html Custom Deleters]<br>
C++ has several types of casts.
When using smart pointers, the default deleter is the <code>delete</code> function but you can also specify your own deleter.
These are the main ones.
 
* <code>const_cast</code>
 
* <code>static_cast</code>
<syntaxhighlight lang="cpp">
* <code>dynamic_cast</code>
# 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);
</syntaxhighlight>
 
 
====Deallocate====
Normally, containers such as <code>std::vector</code> will automatically deallocate memory from the heap when the destructor is called. However, occationally you may want to coerse this deallocation yourself.<br>
There are a few ways to do this:
* Use smart pointers
* Swap
* Call a clear/shrink/deallocate function
Example [https://stackoverflow.com/questions/3054567/right-way-to-deallocate-an-stdvector-object Reference]:
<syntaxhighlight lang="cpp">
// Using smart pointers
std::unique_ptr<std::vector<float>> my_vector = make_unique<std::vector<float>>(99);
my_vector.reset();
 
// Swap
std::vector<float> my_vector(99);
my_vector = std::vector<float>;
// Or alternatively
// std::vector<float>().swap(my_vector);
 
// Swap for cl::Buffer
cl::Buffer my_buf(context, CL_MEM_READ_WRITE, size);
my_buf = cl::Buffer();
 
// Clear and shrink
// Specific to std::vector
std::vector<float> my_vector(99);
my_vector.clear();
my_vector.shrink_to_fit();
 
</syntaxhighlight>
 
===Limits===
<code>#include <limits></code><br>
[https://en.cppreference.com/w/cpp/types/numeric_limits Reference]<br>
C++ has standard macros such as <code>INT_MAX</code>.<br>
The limits header adds these limits for every type.<br>
<syntaxhighlight lang="cpp">
// Equivalent to FLT_MAX
std::numeric_limits<float>::max();
</syntaxhighlight>
 
==STL==
STL is the Standard Template Library.<br>
STL can either refer to the 1994 original STL implementation by Stepanov and Lee from HP or the general set of algorithms, containers, functions, and iterators.<br>
Many STL containers are now built into the standard library (std) of C++.<br>
This section focuses only on the portions of STL which have been incorporated into the C++ standard library.
 
===Simple Containers===
====std::pair====
 
===Sequences===
====std::vector====
====std::list====
 
===Container adaptors===
====std::queue====
====std::stack====
 
===Associative Containers===
Also known as maps or associative arrays.
====std::unordered_set====
<code>#include <unordered_set></code><br>
This is a hashset.<br>
<syntaxhighlight lang="cpp>
std::unordered_set<int> my_set;
// add things to myset
my_set.insert(5);
// Check contains
my_set.find(5) != my_set.end();
</syntaxhighlight>
====std::unordered_map====
 
==Boost==
 


==Programming Styles==
==Programming Styles==
Line 105: Line 286:
[https://gist.github.com/bkaradzic/2e39896bc7d8c34e042b Reference]<br>
[https://gist.github.com/bkaradzic/2e39896bc7d8c34e042b Reference]<br>
Somewhat opposite of modern C++.<br>
Somewhat opposite of modern C++.<br>
Basically only use C++ for its classes. Do everything else C-style.  
Also known as "C with Classes"<br>
Basically only use C++ for its classes. Do everything else C-style.<br>
The main benefit is compatibility with older compilers/libraries and easier understanding for people less familiar with newer C++ features.
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 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 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.
* Don't use anything from STL that allocates memory, unless you don't care about memory management.
* Don't use exceptions.
* Don't use RTTI.


==Boost==
==Useful Libraries==
==STL==
A list of useful libraries
===cxxopts===
[https://github.com/jarro2783/cxxopts Link]<br>
A header-only C++ argument parser.<br>
Note that if you already use Boost, you can use <code>Boost::Program_options</code> instead.
===Eigen===
{{main | Eigen (C++ library)}}
A C++ linear algebra library.