SlideShare a Scribd company logo
CSE 380 C++ Boot Camp
Part 1/2
C++
You
Slides by Jesse Talavera-Greenberg
Disclaimer

I am not the grader for this course

Undergrads can't grade assignments

The boot camp is always part of the course,
but I volunteered to lead it this year

Any opinions expressed are my own and are
not necessarily condoned by McKenna

I don't know very much about DirectX
This Week

No need to download anything this week

Go to www.cppreference.com to follow code

This is your C++ Bible this semester

Online compiler
Basic Structure
#include <iostream>
// Include any header files at the top of the .cpp file to use the classes and
// functions they define
using std::cout;
using std::endl;
// Now do this to use names (or prefix them with “std::”)
// static initializers will be called before main()
// Main entry point of a C++ program
int main(int argc, char** argv, char** env) {
// All these args are optional, third one is not as common
// argc == number of command-line arguments
// argv == the actual arguments as an array of strings
// env == environment variables
cout << "Hello! The name of this program is " << argv[0] << endl;
// Call functions! Do things!
return 0;
// Return code of 0 tells the OS the program exited normally
// Anything else == something went wrong (you decide what the numbers mean)
// Leaving it off implies "return 0"
}
if, else, for, while

Ranged for available, too (we'll come back)
if (somethingIsTrue()) {
for (int i = 0; i < 10; ++i) {
break; // Exactly the same
}
}
else if (somethingElseIsTrue()) {
while (true) break;
// You can omit braces for single statements like in Java
}
else {
do {
continue; // Exactly the same
} while (false);
}
switch
●
Same, except cases can't be strings
switch (someInteger) { // All okay
case 0:
break;
case SOME_CONSTANT:
break;
default:
// nop
}
switch (someString) { // ERROR
case "No way":
case "Too bad":
case "Don't bother":
default:
// nop
}
try/catch/throw

There is no finally

Use destructors instead (we'll come back)
using std::exception;
try {
functionThatMightThrowException(); // No checked exceptions in C++
throw exception("No new statement; we'll come back to this");
}
catch (exception e) {
std::cout << e.what(); // Print the exception info
}
try {
throw 5;
// You can throw anything in C++
}
catch (int i) {
// Stick to exception objects and their subclasses, though
}
catch (...) {
// Catch anything, but you can't access it; can only be used last
}
Fundamental types

Sizes are not well-
defined like in Java

No byte (use
uint8_t)

boolean → bool

Use nullptr instead
of null or NULL

Signed and unsigned
types

signed types are the
same

unsigned types
double the max value,
but can't represent
negative numbers

Need a specific number size?

First #include <cstdint>

Then use std::u?int(8|16|32|64)_t
typedef and typeid
#include <cstdint>
#include <iostream>
#include <typeinfo>
// ^ Must include typeinfo to use the typeid operator
typedef std::uint8_t byte;
// Declares another name for the same type
// Syntax:
// typedef existing_type new_name;
using std::cout;
using std::endl;
int main() {
std::uint8_t a = 5;
byte b = a; // Totally okay; the distinction is compile-time only
cout << typeid(std::uint8_t).name() << endl;
cout << typeid(byte).name() << endl;
// Both printouts will be implementation-defined, but identical
/*
Common standard typedefs:
size_t: Sizes of objects (usually an unsigned int)
ptrdiff_t: Difference between pointers (usually an unsigned int or long)
std::string: Convenient form of std::basic_string<char>
*/
}
Declaring Variables
#include <string>
#include <vector>
using std::string;
using std::vector;
int main() {
string empty; // default constructor
string empty2(); // default constructor with parens
string value = "I'm really a char*";
string value2("Parens are fine, too");
string copy = value; // This is a COPY; NOT A REFERENCE
string& ref = value; // THIS is a reference
const string& constref = value; // A reference whose object can't be modified
// All of an object's members are initialized!
string* ptr; // Unassigned pointer; not necessarily nullptr
vector<int> ints = {1, 2, 3, 4, 5, 6}; // You can initialize collections this way
}
Undefined behavior

Whenever something happens in Java, you can
rely on something else to happen

C++ lets the compiler do anything it wants in
certain situations

For performance reasons, mostly

Many, many ways to do this

Do not rely on undefined behavior
Common undefined
behaviors
#include <string>
#include <cstdint>
#include <limits>
int32_t something(int32_t param) {
if (param > 0) return param;
// No return down here; now what?
}
std::string& returnsALocal() {
std::string reference = "Why are you doing this";
return reference; // Uh-oh
}
int main() {
int32_t a = std::numeric_limits<int32_t>::max();
a++; // Oops
int32_t* pointer; // Could be nullptr, could be garbage
int32_t number = *pointer; // BAD
int32_t[10] array;
number = array[12]; // WTF
}
namespace
#include <iostream>
#include <string>
#include <array>
#include <utility>
using namespace std;
// ^ Don't do this for the same reason you don't do java.util.*
namespace sbcs {
// Nest them as much as you'd like
namespace cse380 {
struct Game {
string name;
string teamName;
array<string, 3> members;
};
}
namespace cse381 {
typedef pair<string, string> Team;
}
}
int main() {
sbcs::cse380::Game game; // Fully-qualified type name
using sbcs::cse381::Team; // Or use it in the current namespace (global in this case)
Team team("Jesse", "Karl");
}
The Preprocessor
#include <iostream>
// Use <angle_brackets> for standard library/third-party code, "quotes" for your own
#define DEBUG
// You can also add #defines through your build system (e.g. the command line or
// your Visual Studio project file)
// #define WINDOWS
// #define MAC
// ^ Uncomment one of these
using std::cout;
using std::endl;
int main() {
#ifdef DEBUG
cout << "Logging! Or sanity checking!" << endl;
#endif
#ifdef WINDOWS
cout << "Use DirectX!" << endl;
#else
cout << "Use OpenGL!" << endl;
#endif
#ifdef MAC
#error "Jesse doesn't like Apple"
// ^ Intentionally causes a compiler error
#endif
}
assert/static_assert
#include <cassert>
#include <type_traits>
// #define NDEBUG
// ^ Uncomment this or define it in the build system to disable asserts
using std::is_base_of;
using std::is_same;
template<class T, class U>
void failIfUnrelated() {
static_assert(
is_base_of<T, U>::value
|| is_base_of<U, T>::value
|| is_same<T, U>::value,
"Both types should be the same, or one should be a parent of the other"
);
}
class Parent {};
class Child : public Parent {};
int main() {
assert(1 + 1 == 2);
assert(true && "Idiom for providing informative text in an assert()");
failIfUnrelated<int, int>(); // Okay
failIfUnrelated<int, float>(); // Causes a compiler error, as desired
failIfUnrelated<Parent, Child>(); // Okay
}
enum
#include <iostream>
using std::cout;
using std::endl;
enum class Direction {
North,
South,
East,
West, // Trailing comma is okay
};
// NOT OBJECTS; just ints with some compile-time meaning
enum class Speakers {
Mute = 0, // Assigning values is okay
Mono = 1,
Stereo = 2,
Surround = 4
};
int main() {
Direction dir = Direction::North;
Speakers audio = Speakers::Stereo;
audio = Speakers(4); // Make sure int is a valid Speakers value!
cout << int(audio) << endl;
// int <-> enum class conversions must be explicit
}
Pointers
#include <string>
using std::string;
int main() {
string a = "I'm a little teapot";
string* ptr = &a; // &some_object returns the address of some_object
string b = *ptr; // *some_pointer dereferences
int ints[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// Raw arrays are pointers
int* int_ptr = ints; // Points to ints[0]
int* int_ptr2 = ints + 1; // Points to ints[1]
// Increments the address sizeof(int) bytes
int** double_array = &int_ptr;
// Pointers to pointers okay; never usually need more than two**
void* pointer_to_anything = ints;
// Pointer to arbitrary data; very error-prone and unsafe; avoid unless you know
// exactly why you need one
pointer_to_anything = nullptr;
// nullptr == Java's null; assignable to any pointer type, but not to objects
float* garbage; // Uninitialized pointer; value is undefined
// Could be garbage, could be nullptr; initialize it ASAP!
}
References
#include <string>
#include <iostream>
using namespace std; // Only for slide space constraints
class StringHolder {
public:
StringHolder(const string& str) : _str(str) {}
const string& getStringReference() const { return this->_str; }
string getStringCopy() const { return this->_str; }
void append(const string& str) { this->_str += str; }
// ^ Passes an unmodifiable reference rather than a copy
private:
string _str;
};
int main() {
StringHolder holder("France");
const string& a = holder.getStringReference();
string b = holder.getStringCopy();
cout << (a == b) << endl; // True; comparing object values
cout << (&a == &b) << endl; // False; different addresses, different objects
holder.append(b);
cout << holder.getStringReference() << endl; // FranceFrance
}
Pointers Vs. References
(Similarities)

Access large objects without copying them

Left dangling (invalid) if the referenced object
is deallocated

No way to check for this

Will likely cause a crash if you try to use it

Both can point to an instance of the given type's
superclass

Both compiled to similar machine code

Multiple pointers/references can refer to one
object
Pointers Vs. References
(Differences)

Can represent
absence of data

More prone to
becoming invalid

Syntax needed to
convert between
pointers and objects

Can be assigned to
different objects

Always initialized with
a valid object

No syntax needed to
use references aside
from declarations or
method signatures

Always points to one
location in memory

Easier to deal with
objects that shouldn't
change
new/delete
#include <string>
using std::string;
void wasteMemory() {
string stack_allocated = "I disappear when I go out of scope";
string* wasted = new string(
"I only disappear when explicitly deallocated"
);
string* cleaned = new string("I'm about to get cleaned up properly");
delete cleaned;
}
int main() {
for (int i = 0; i < 10000; i++) {
wasteMemory();
}
// stack_allocated disappeared when wasteMemory() returned
// All instances of wasted are still in memory
// cleaned disappeared when "delete cleaned;" was called
// See: Scope vs. Lifetime
}
Exceptions
#include <iostream>
#include <string>
#include <exception>
#include <array>
using namespace std; // Again, slide space constraints
int main() {
array<int, 5> ints = {1, 2, 3, 4, 5};
try {
cout << ints.at(10) << endl; // at() checks bounds, operator[] doesn't
}
catch (const out_of_range& e) { // You can (and should) catch by reference
cout << "Out of range in an array" << endl;
}
catch (const runtime_error& e) {
cout << "Didn't see this coming: " << e.what() << endl;
}
catch (const exception& e) {
cout << "Unknown exception: " << e.what() << endl;
}
catch (...) {
cout << "WTF?" << endl;
}
// There is no finally clause; use destructors to guarantee exception safety
}
Declaring Classes
// public/protected/private semantics same as in Java
// no specifier == private in classes, public in structs
class ItHoldsThings {
public:
int cantBeOverridden(int a, int b) {
// Technically you can, but things get weird
return this->_integer + b;
}
virtual float canBeOverridden(const double d) {
// virtual == overrideable
return d * 2;
}
virtual void abstractMethod() = 0;
protected:
float _number;
private:
int _integer;
}; // Don't forget the semicolon
// When a class is constructed, ALL of its members are too
Constructors
#include <string>
using std::string;
class StringWrapper {
public:
StringWrapper() { /* other code here */ } // _str == ""
// Default constructor can be auto-generated with some caveats (see the wiki)
StringWrapper(const string& value) : _str(value) {} // _str == value
// Copy constructor can be auto-generated (but see wiki)
// Base class constructors are called like this, too
private:
string _str;
// All members are initialized on construction, whether you like it or not
};
int main() {
StringWrapper a;
StringWrapper b("There will be a copy of me in c");
StringWrapper c(b);
}
// Using constructors to allocate resources and destructors to clean them up is
// called Resource Acquisition Is Initialization (RAII). Only needed for low-level
// resources; high-level classes like std::iostream do RAII themselves.
#include <cstdlib>
using std::malloc;
using std::free;
class LotsOfResources {
public:
LotsOfResources() {
_floats = new float[64];
_buffer = malloc(64);
}
~LotsOfResources() { // Called when this object's lifetime ends
delete[] _floats; // Remember the [] when deleting a raw array
free(_buffer);
}
private:
float* _floats;
void* _buffer;
};
int main() {
LotsOfResources* resources = new LotsOfResources;
delete resources; // No memory leaks!
}
Destructors
Abstract Classes/Inheritance
#include <exception>
#include <iostream>
// There are no interfaces; use abstract classes without any concrete methods
struct ProgramCrasher {
virtual void crash() = 0; // "= 0" means the method is abstract
// virtual == method can be overridden
// only one abstract method needed to define a class as abstract
};
struct IPastryChef {
virtual void bake() = 0;
};
struct SegfaultCrasher : public ProgramCrasher {
// Actually several types of inheritance; it's complicated, just use public
void crash() override {
int* a;
int b = *a;
}
};
// Multiple inheritance; don't do it if more than one parent class is not an interface
struct ExceptionCrasher : public ProgramCrasher, public IPastryChef {
void crash() override { throw std::exception(); }
void bake() override {
std::cout << "This is just my day jobn";
}
};
(static|dynamic)_cast
#include <iostream>
#include <string>
using namespace std; // Slide space constraints
struct Base {
virtual ~Base() {}
string baseMethod() { return "base"; }
};
struct Derived: Base {
virtual string derivedMethod() { return "derived"; }
};
int main()
{
Base* b1 = new Derived;
Derived* d1_s = dynamic_cast<Derived*>(b1);
cout << d1_s << ' ' << d1_s->baseMethod() << ' ' << d1_s->derivedMethod() << endl;
// Checking at runtime that you're casting to the right type
Derived* d1_d = static_cast<Derived*>(b1);
cout << d1_d << ' ' << d1_d->baseMethod() << ' ' << d1_d->derivedMethod() << endl;
// Static (compile-time) downcasts are OK (and faster) if you know you're
// casting to the right type
Base* b2 = new Base;
Derived* d2_d = dynamic_cast<Derived*>(b2);
cout << d2_d << endl;
// Cast was not valid, so dynamic_cast returned nullptr
// If it were a reference, it would've thrown std::bad_cast
Derived* d2_s = static_cast<Derived*>(b2);
// cout << d2_s << ' ' << d2_s->baseMethod() << ' ' << d2_s->derivedMethod() << endl;
// ^ This is undefined, since the cast is wrong (and not checked at runtime)
delete b1; // Remember to clean up!
delete b2;
}
Templates
#include <string>
#include <vector>
template<class T>
class Value {
public:
Value(const T& data) : _data(data) {}
const T& getData() { return this->_data; }
private:
T _data;
};
// Templates are used A LOT in the standard library
using std::string;
using std::vector;
int main() {
Value<string> str("My name is Beavis");
Value<vector<int>> ints({1, 2, 3, 4, 5, 6});
// Two different classes, with two different bits of machine code
}
Templates
#include <iostream>
#include <array>
#include <vector>
#include <string>
using namespace std; // Slide space constraints
template<class T>
void printIt(const T& object) {
cout << object << endl;
}
template<class Container>
void needsABeginMethod(Container& container) {
auto iterator = container.begin();
// The begin() method returns an iterator
}
int main() {
printIt(42); // Type parameters in function templates are usually inferred
printIt<float>(7.3); // You can specify them explicitly if you need to
array<int, 3> ints = {1, 2, 3};
vector<int> vec = {5, 6, 7, 8, 9};
string str = "Strings are containers";
needsABeginMethod(ints);
needsABeginMethod(vec);
needsABeginMethod(str);
// needsABeginMethod(47); ERROR: ints don't have such a method
}
Templates
#include <array>
#include <iostream>
#include <typeinfo>
#include <string>
using namespace std; // slide space limits
template<class T, int ArrayLength = 10>
class SomeTypedefs {
public:
SomeTypedefs() = delete; // Prevent instantiation
typedef T Type;
typedef T* Pointer;
typedef T& Reference;
typedef T RawArray[ArrayLength];
typedef array<T, ArrayLength> STLArray;
};
// The standard library does this a lot ^
int main() {
cout << typeid(SomeTypedefs<int>::Type).name() << endl;
cout << typeid(SomeTypedefs<float>::Pointer).name() << endl;
cout << typeid(SomeTypedefs<string>::Reference).name() << endl;
cout << typeid(SomeTypedefs<int, 14>::RawArray).name() << endl;
cout << typeid(SomeTypedefs<double, 3>::STLArray).name() << endl;
}
const
#include <string>
using std::string;
const int SOME_CONSTANT = 34;
const string ANOTHER_CONSTANT = "More type-safe than macros!";
class ConstStuff {
public:
int getData() const { // The method doesn't modify the object
return this->_data;
}
const string& getText() const {
// Gives you an immutable reference to _text; you must assign it to
// a const std::string& if you don't want to copy it
return this->_text;
}
void concatenate(const string& str) {
// str itself can't be modified, and it's not copied
this->_text += str;
}
private:
int _data;
string _text;
};
// Attempting to violate const-correctness through runtime tricks is UB
Operator Overloading
#include <iostream>
using std::cout;
using std::endl;
using std::ostream; // cout is an ostream
struct Vector2 {
float x, y;
Vector2(const float x, const float y) : x(x), y(y) {}
Vector2 operator+(const Vector2& other) {
return Vector2(x + other.x, y + other.y);
}
};
// This is how most types in the standard library are printed out
ostream& operator<<(ostream& out, const Vector2& v){
return out << '[' << v.x << ", " << v.y << ']';
}
int main() {
Vector2 a(1, 2);
Vector2 b(2, 1);
Vector2 c = a + b;
cout << c << endl;
}
Strings to numbers and back
#include <string>
#include <cstdlib>
using std::string;
using std::stoi;
using std::stol;
using std::stoll;
using std::size_t;
// sto(i|u?ll?|f|l?d) is available
using std::to_string; // to_wstring is available too
int main() {
int a = stoi("42");
// a == 42
long b = stol(" 0x09", nullptr, 16); // Strips whitespace, reads as base 16
// b == 9
size_t first_nonnumeric_char_index;
long long c = stoll("12lbs", &first_nonnumeric_char_index, 0);
// c == 12, first_nonnumeric_char_index == 2
// base-0 means assume either base 8, 10, or 16 depending on the prefix
string back = to_string(c); // 12
}
Data Structures
●
The usual suspects
●
You must #include <class_name>
●
Prefer std::array<SomeType, Length> to SomeType[Length]
●
std::vector<T> ↔ java.util.ArrayList<T>
●
std::deque<T> ↔ java.util.ArrayQueue<T>
●
std::list<T> ↔ java.util.LinkedList<T>
●
std::set<T> ↔ java.util.TreeSet<T>
●
std::map<T, U> ↔ java.util.TreeMap<T, U>
●
std::unordered_set<T> ↔ java.util.HashSet<T>
●
std::unordered_map<T, U> ↔ java.util.HashMap<T, U>
●
std::stack<T> ↔ java.util.Stack<T>
●
std::priority_queue<T> ↔ java.util.PriorityQueue<T>
Random numbers
#include <iostream>
#include <random>
using std::cout;
using std::default_random_engine;
using std::endl;
using std::normal_distribution;
using std::random_device;
int main()
{
random_device seed;
default_random_engine random(seed());
// Seed the generator with a totally random number (as opposed to
// something like the system time)
normal_distribution<float> normal(0, 1); // mean == 0, stddev == 1
for (int i = 0; i < 100; ++i) {
cout << normal(random) << ' ';
// Use seed instead of random if you REALLY want randomness
// (but that will be slower)
}
cout << endl;
}
String Concatenation
#include <iostream>
#include <sstream>
#include <string>
#include <iomanip>
using std::string;
using std::stringstream;
using std::cout;
using std::endl;
using std::setprecision;
int main()
{
float x = 5.6435221, y = 7.1453634545, z = -23.452354215;
stringstream coords;
coords << "DEBUG LOGn"
<< "tPosition: [" << setprecision(4)
<< x << ", " << y << ", " << z << "]n";
cout << coords.str() << endl;
// Use stringstream for formatted output like in debug consoles
// Small amounts of pre-existing strings can be appended with operator+
}
Iterators
#include <array>
#include <string>
#include <iostream>
using std::array;
using std::cout;
using std::endl;
using std::string;
int main() {
array<string, 5> strings = {"France", "Spain", "China", "America", "Sweden"};
// No iterators
for (int i = 0; i < strings.size(); i++) {
cout << strings[i] << ' ';
}
cout << endl;
// The clunky way
for (array<string, 5>::iterator it = strings.begin(); it != strings.end(); it++) {
cout << *it << ' ';
}
cout << endl;
// The C++11 way
for (const string& s : strings) {
cout << s << ' ';
}
cout << endl;
}
Anonymous Functions and
<algorithm>
#include <array>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std; // For slide space
int main() {
array<int, 10> ints = {5, 7, 1, 2, 3, 9, 2, 1, 4, 2};
function<bool(int)> isEven = [](int n) -> bool {
return n % 2 == 0;
};
// () can be omitted if there are no parameters
function<void(void)> printInts = [&ints] {
for (int i : ints) {
cout << i << ' ';
}
cout << endl;
};
printInts();
// return type can be omitted if it can be deduced
transform(ints.begin(), ints.end(), ints.begin(), [&isEven](int i) {
// [&something] captures something by reference, [something] by value
return isEven(i) ? i : i * 2;
}); // ^ Doubles all odd numbers
printInts();
}
Time
#include <chrono>
#include <iostream>
#include <thread>
using std::cout;
using std::endl;
using std::this_thread::sleep_for;
using std::chrono::duration;
using std::chrono::duration_cast;
using std::chrono::system_clock;
typedef duration<float> secondsf; // Seconds, represented as a float
// Standard typedefs for seconds, milliseconds, hours, etc. exist, too
const int FPS = 60;
int main() {
secondsf ms_per_frame(1.0 / FPS);
system_clock::time_point start = system_clock::now();
for (int i = 0; i < 300; i++) {
sleep_for(ms_per_frame);
cout << "Frame #" << i << endl;
}
cout << "Elapsed time: "
<< duration_cast<secondsf>(system_clock::now() - start).count()
<< " secondsn";
}
Next Week

Compiling and linking code

Using Visual Studio

Overview of popular C++ tools

Building and using Box2D

This is part of your homework!

More Related Content

What's hot

Exception Handling in the C++ Constructor
Exception Handling in the C++ ConstructorException Handling in the C++ Constructor
Exception Handling in the C++ Constructor
Somenath Mukhopadhyay
 
PVS-Studio is there to help CERN: analysis of Geant4 project
PVS-Studio is there to help CERN: analysis of Geant4 projectPVS-Studio is there to help CERN: analysis of Geant4 project
PVS-Studio is there to help CERN: analysis of Geant4 project
PVS-Studio
 
Checking Clang 11 with PVS-Studio
Checking Clang 11 with PVS-StudioChecking Clang 11 with PVS-Studio
Checking Clang 11 with PVS-Studio
Andrey Karpov
 
Handling Exceptions In C &amp; C++[Part A]
Handling Exceptions In C &amp; C++[Part A]Handling Exceptions In C &amp; C++[Part A]
Handling Exceptions In C &amp; C++[Part A]
ppd1961
 
JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.
JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.
JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.
Jin-Hwa Kim
 
Exception Handling1
Exception Handling1Exception Handling1
Exception Handling1
guest739536
 
Js fwdays unit tesing javascript(by Anna Khabibullina)
Js fwdays unit tesing javascript(by Anna Khabibullina)Js fwdays unit tesing javascript(by Anna Khabibullina)
Js fwdays unit tesing javascript(by Anna Khabibullina)
Anna Khabibullina
 
JS Frameworks Day April,26 of 2014
JS Frameworks Day April,26 of 2014JS Frameworks Day April,26 of 2014
JS Frameworks Day April,26 of 2014
DA-14
 
Checking VirtualDub
Checking VirtualDubChecking VirtualDub
Checking VirtualDub
Andrey Karpov
 
Handling Exceptions In C &amp; C++ [Part B] Ver 2
Handling Exceptions In C &amp; C++ [Part B] Ver 2Handling Exceptions In C &amp; C++ [Part B] Ver 2
Handling Exceptions In C &amp; C++ [Part B] Ver 2
ppd1961
 
PVS-Studio delved into the FreeBSD kernel
PVS-Studio delved into the FreeBSD kernelPVS-Studio delved into the FreeBSD kernel
PVS-Studio delved into the FreeBSD kernel
PVS-Studio
 
Linux version of PVS-Studio couldn't help checking CodeLite
Linux version of PVS-Studio couldn't help checking CodeLiteLinux version of PVS-Studio couldn't help checking CodeLite
Linux version of PVS-Studio couldn't help checking CodeLite
PVS-Studio
 
Going On with the Check of Geant4
Going On with the Check of Geant4Going On with the Check of Geant4
Going On with the Check of Geant4
Andrey Karpov
 
Checking the Cross-Platform Framework Cocos2d-x
Checking the Cross-Platform Framework Cocos2d-xChecking the Cross-Platform Framework Cocos2d-x
Checking the Cross-Platform Framework Cocos2d-x
Andrey Karpov
 
Sony C#/.NET component set analysis
Sony C#/.NET component set analysisSony C#/.NET component set analysis
Sony C#/.NET component set analysis
PVS-Studio
 
Re-analysis of Umbraco code
Re-analysis of Umbraco codeRe-analysis of Umbraco code
Re-analysis of Umbraco code
PVS-Studio
 
CppCat Static Analyzer Review
CppCat Static Analyzer ReviewCppCat Static Analyzer Review
CppCat Static Analyzer Review
Andrey Karpov
 
The operation principles of PVS-Studio static code analyzer
The operation principles of PVS-Studio static code analyzerThe operation principles of PVS-Studio static code analyzer
The operation principles of PVS-Studio static code analyzer
Andrey Karpov
 
One Careful Owner
One Careful OwnerOne Careful Owner
One Careful Owner
Kevlin Henney
 
From Elixir to Akka (and back) - ElixirConf Mx 2017
From Elixir to Akka (and back) - ElixirConf Mx 2017From Elixir to Akka (and back) - ElixirConf Mx 2017
From Elixir to Akka (and back) - ElixirConf Mx 2017
Agustin Ramos
 

What's hot (20)

Exception Handling in the C++ Constructor
Exception Handling in the C++ ConstructorException Handling in the C++ Constructor
Exception Handling in the C++ Constructor
 
PVS-Studio is there to help CERN: analysis of Geant4 project
PVS-Studio is there to help CERN: analysis of Geant4 projectPVS-Studio is there to help CERN: analysis of Geant4 project
PVS-Studio is there to help CERN: analysis of Geant4 project
 
Checking Clang 11 with PVS-Studio
Checking Clang 11 with PVS-StudioChecking Clang 11 with PVS-Studio
Checking Clang 11 with PVS-Studio
 
Handling Exceptions In C &amp; C++[Part A]
Handling Exceptions In C &amp; C++[Part A]Handling Exceptions In C &amp; C++[Part A]
Handling Exceptions In C &amp; C++[Part A]
 
JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.
JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.
JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.
 
Exception Handling1
Exception Handling1Exception Handling1
Exception Handling1
 
Js fwdays unit tesing javascript(by Anna Khabibullina)
Js fwdays unit tesing javascript(by Anna Khabibullina)Js fwdays unit tesing javascript(by Anna Khabibullina)
Js fwdays unit tesing javascript(by Anna Khabibullina)
 
JS Frameworks Day April,26 of 2014
JS Frameworks Day April,26 of 2014JS Frameworks Day April,26 of 2014
JS Frameworks Day April,26 of 2014
 
Checking VirtualDub
Checking VirtualDubChecking VirtualDub
Checking VirtualDub
 
Handling Exceptions In C &amp; C++ [Part B] Ver 2
Handling Exceptions In C &amp; C++ [Part B] Ver 2Handling Exceptions In C &amp; C++ [Part B] Ver 2
Handling Exceptions In C &amp; C++ [Part B] Ver 2
 
PVS-Studio delved into the FreeBSD kernel
PVS-Studio delved into the FreeBSD kernelPVS-Studio delved into the FreeBSD kernel
PVS-Studio delved into the FreeBSD kernel
 
Linux version of PVS-Studio couldn't help checking CodeLite
Linux version of PVS-Studio couldn't help checking CodeLiteLinux version of PVS-Studio couldn't help checking CodeLite
Linux version of PVS-Studio couldn't help checking CodeLite
 
Going On with the Check of Geant4
Going On with the Check of Geant4Going On with the Check of Geant4
Going On with the Check of Geant4
 
Checking the Cross-Platform Framework Cocos2d-x
Checking the Cross-Platform Framework Cocos2d-xChecking the Cross-Platform Framework Cocos2d-x
Checking the Cross-Platform Framework Cocos2d-x
 
Sony C#/.NET component set analysis
Sony C#/.NET component set analysisSony C#/.NET component set analysis
Sony C#/.NET component set analysis
 
Re-analysis of Umbraco code
Re-analysis of Umbraco codeRe-analysis of Umbraco code
Re-analysis of Umbraco code
 
CppCat Static Analyzer Review
CppCat Static Analyzer ReviewCppCat Static Analyzer Review
CppCat Static Analyzer Review
 
The operation principles of PVS-Studio static code analyzer
The operation principles of PVS-Studio static code analyzerThe operation principles of PVS-Studio static code analyzer
The operation principles of PVS-Studio static code analyzer
 
One Careful Owner
One Careful OwnerOne Careful Owner
One Careful Owner
 
From Elixir to Akka (and back) - ElixirConf Mx 2017
From Elixir to Akka (and back) - ElixirConf Mx 2017From Elixir to Akka (and back) - ElixirConf Mx 2017
From Elixir to Akka (and back) - ElixirConf Mx 2017
 

Viewers also liked

Escuela de formacion de soldados
Escuela de formacion de soldadosEscuela de formacion de soldados
Escuela de formacion de soldados
David Duran
 
bladescope
bladescopebladescope
bladescope
Vishnu Mohanan
 
5 слов об общении в интернете на английском языке - chatter
5 слов об общении в интернете на английском языке - chatter5 слов об общении в интернете на английском языке - chatter
5 слов об общении в интернете на английском языке - chatter
Ruslan Lyashchuk
 
Grupo Única - Carta A ComissãO EuropéIa
Grupo Única - Carta A ComissãO  EuropéIaGrupo Única - Carta A ComissãO  EuropéIa
Grupo Única - Carta A ComissãO EuropéIa
BeefPoint
 
5 Best ETFs For November
5 Best ETFs For November5 Best ETFs For November
5 Best ETFs For November
ETF Trading Research
 
Box2D
Box2DBox2D
Напитки на английском языке - Drinks
Напитки на английском языке - DrinksНапитки на английском языке - Drinks
Напитки на английском языке - Drinks
Ruslan Lyashchuk
 
11.1
11.111.1
11.1
rakul-oi
 
Phylogenetics of the grass family (poaceae)
Phylogenetics of the grass family (poaceae)Phylogenetics of the grass family (poaceae)
Phylogenetics of the grass family (poaceae)
Vishnu Mohanan
 
Weather & Climate
Weather & ClimateWeather & Climate
Weather & Climate
DavidProfeSoc
 

Viewers also liked (11)

Escuela de formacion de soldados
Escuela de formacion de soldadosEscuela de formacion de soldados
Escuela de formacion de soldados
 
bladescope
bladescopebladescope
bladescope
 
5 слов об общении в интернете на английском языке - chatter
5 слов об общении в интернете на английском языке - chatter5 слов об общении в интернете на английском языке - chatter
5 слов об общении в интернете на английском языке - chatter
 
Nyhedsbrev_maj_web
Nyhedsbrev_maj_webNyhedsbrev_maj_web
Nyhedsbrev_maj_web
 
Grupo Única - Carta A ComissãO EuropéIa
Grupo Única - Carta A ComissãO  EuropéIaGrupo Única - Carta A ComissãO  EuropéIa
Grupo Única - Carta A ComissãO EuropéIa
 
5 Best ETFs For November
5 Best ETFs For November5 Best ETFs For November
5 Best ETFs For November
 
Box2D
Box2DBox2D
Box2D
 
Напитки на английском языке - Drinks
Напитки на английском языке - DrinksНапитки на английском языке - Drinks
Напитки на английском языке - Drinks
 
11.1
11.111.1
11.1
 
Phylogenetics of the grass family (poaceae)
Phylogenetics of the grass family (poaceae)Phylogenetics of the grass family (poaceae)
Phylogenetics of the grass family (poaceae)
 
Weather & Climate
Weather & ClimateWeather & Climate
Weather & Climate
 

Similar to C++ Boot Camp Part 1

Functions And Header Files In C++ | Bjarne stroustrup
Functions And Header Files In C++ | Bjarne stroustrupFunctions And Header Files In C++ | Bjarne stroustrup
Functions And Header Files In C++ | Bjarne stroustrup
SyedHaroonShah4
 
C++ Core Guidelines
C++ Core GuidelinesC++ Core Guidelines
C++ Core Guidelines
Thomas Pollak
 
C++11: Rvalue References, Move Semantics, Perfect Forwarding
C++11: Rvalue References, Move Semantics, Perfect ForwardingC++11: Rvalue References, Move Semantics, Perfect Forwarding
C++11: Rvalue References, Move Semantics, Perfect Forwarding
Francesco Casalegno
 
JAVA Tutorial- Do's and Don'ts of Java programming
JAVA Tutorial- Do's and Don'ts of Java programmingJAVA Tutorial- Do's and Don'ts of Java programming
JAVA Tutorial- Do's and Don'ts of Java programming
Keshav Kumar
 
JAVA Tutorial- Do's and Don'ts of Java programming
JAVA Tutorial- Do's and Don'ts of Java programmingJAVA Tutorial- Do's and Don'ts of Java programming
JAVA Tutorial- Do's and Don'ts of Java programming
Keshav Kumar
 
Static types on javascript?! Type checking approaches to ensure healthy appli...
Static types on javascript?! Type checking approaches to ensure healthy appli...Static types on javascript?! Type checking approaches to ensure healthy appli...
Static types on javascript?! Type checking approaches to ensure healthy appli...
Arthur Puthin
 
Clean & Typechecked JS
Clean & Typechecked JSClean & Typechecked JS
Clean & Typechecked JS
Arthur Puthin
 
Day 1
Day 1Day 1
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
corehard_by
 
Introduction to Dart
Introduction to DartIntroduction to Dart
Introduction to Dart
Ramesh Nair
 
C++aptitude questions and answers
C++aptitude questions and answersC++aptitude questions and answers
C++aptitude questions and answers
sheibansari
 
Core java concepts
Core java concepts Core java concepts
Core java concepts
javeed_mhd
 
Vocabulary Types in C++17
Vocabulary Types in C++17Vocabulary Types in C++17
Vocabulary Types in C++17
Bartlomiej Filipek
 
My programming final proj. (1)
My programming final proj. (1)My programming final proj. (1)
My programming final proj. (1)
aeden_brines
 
Java tutorial PPT
Java tutorial  PPTJava tutorial  PPT
Java tutorial PPT
Intelligo Technologies
 
Java tutorial PPT
Java tutorial PPTJava tutorial PPT
Java tutorial PPT
Intelligo Technologies
 
Core Java
Core JavaCore Java
Core Java
Khasim Saheb
 
Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)
David McCarter
 
Back to the Future with TypeScript
Back to the Future with TypeScriptBack to the Future with TypeScript
Back to the Future with TypeScript
Aleš Najmann
 
C to perl binding
C to perl bindingC to perl binding
C to perl binding
Shmuel Fomberg
 

Similar to C++ Boot Camp Part 1 (20)

Functions And Header Files In C++ | Bjarne stroustrup
Functions And Header Files In C++ | Bjarne stroustrupFunctions And Header Files In C++ | Bjarne stroustrup
Functions And Header Files In C++ | Bjarne stroustrup
 
C++ Core Guidelines
C++ Core GuidelinesC++ Core Guidelines
C++ Core Guidelines
 
C++11: Rvalue References, Move Semantics, Perfect Forwarding
C++11: Rvalue References, Move Semantics, Perfect ForwardingC++11: Rvalue References, Move Semantics, Perfect Forwarding
C++11: Rvalue References, Move Semantics, Perfect Forwarding
 
JAVA Tutorial- Do's and Don'ts of Java programming
JAVA Tutorial- Do's and Don'ts of Java programmingJAVA Tutorial- Do's and Don'ts of Java programming
JAVA Tutorial- Do's and Don'ts of Java programming
 
JAVA Tutorial- Do's and Don'ts of Java programming
JAVA Tutorial- Do's and Don'ts of Java programmingJAVA Tutorial- Do's and Don'ts of Java programming
JAVA Tutorial- Do's and Don'ts of Java programming
 
Static types on javascript?! Type checking approaches to ensure healthy appli...
Static types on javascript?! Type checking approaches to ensure healthy appli...Static types on javascript?! Type checking approaches to ensure healthy appli...
Static types on javascript?! Type checking approaches to ensure healthy appli...
 
Clean & Typechecked JS
Clean & Typechecked JSClean & Typechecked JS
Clean & Typechecked JS
 
Day 1
Day 1Day 1
Day 1
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
 
Introduction to Dart
Introduction to DartIntroduction to Dart
Introduction to Dart
 
C++aptitude questions and answers
C++aptitude questions and answersC++aptitude questions and answers
C++aptitude questions and answers
 
Core java concepts
Core java concepts Core java concepts
Core java concepts
 
Vocabulary Types in C++17
Vocabulary Types in C++17Vocabulary Types in C++17
Vocabulary Types in C++17
 
My programming final proj. (1)
My programming final proj. (1)My programming final proj. (1)
My programming final proj. (1)
 
Java tutorial PPT
Java tutorial  PPTJava tutorial  PPT
Java tutorial PPT
 
Java tutorial PPT
Java tutorial PPTJava tutorial PPT
Java tutorial PPT
 
Core Java
Core JavaCore Java
Core Java
 
Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)
 
Back to the Future with TypeScript
Back to the Future with TypeScriptBack to the Future with TypeScript
Back to the Future with TypeScript
 
C to perl binding
C to perl bindingC to perl binding
C to perl binding
 

C++ Boot Camp Part 1

  • 1. CSE 380 C++ Boot Camp Part 1/2 C++ You Slides by Jesse Talavera-Greenberg
  • 2. Disclaimer  I am not the grader for this course  Undergrads can't grade assignments  The boot camp is always part of the course, but I volunteered to lead it this year  Any opinions expressed are my own and are not necessarily condoned by McKenna  I don't know very much about DirectX
  • 3. This Week  No need to download anything this week  Go to www.cppreference.com to follow code  This is your C++ Bible this semester  Online compiler
  • 4. Basic Structure #include <iostream> // Include any header files at the top of the .cpp file to use the classes and // functions they define using std::cout; using std::endl; // Now do this to use names (or prefix them with “std::”) // static initializers will be called before main() // Main entry point of a C++ program int main(int argc, char** argv, char** env) { // All these args are optional, third one is not as common // argc == number of command-line arguments // argv == the actual arguments as an array of strings // env == environment variables cout << "Hello! The name of this program is " << argv[0] << endl; // Call functions! Do things! return 0; // Return code of 0 tells the OS the program exited normally // Anything else == something went wrong (you decide what the numbers mean) // Leaving it off implies "return 0" }
  • 5. if, else, for, while  Ranged for available, too (we'll come back) if (somethingIsTrue()) { for (int i = 0; i < 10; ++i) { break; // Exactly the same } } else if (somethingElseIsTrue()) { while (true) break; // You can omit braces for single statements like in Java } else { do { continue; // Exactly the same } while (false); }
  • 6. switch ● Same, except cases can't be strings switch (someInteger) { // All okay case 0: break; case SOME_CONSTANT: break; default: // nop } switch (someString) { // ERROR case "No way": case "Too bad": case "Don't bother": default: // nop }
  • 7. try/catch/throw  There is no finally  Use destructors instead (we'll come back) using std::exception; try { functionThatMightThrowException(); // No checked exceptions in C++ throw exception("No new statement; we'll come back to this"); } catch (exception e) { std::cout << e.what(); // Print the exception info } try { throw 5; // You can throw anything in C++ } catch (int i) { // Stick to exception objects and their subclasses, though } catch (...) { // Catch anything, but you can't access it; can only be used last }
  • 8. Fundamental types  Sizes are not well- defined like in Java  No byte (use uint8_t)  boolean → bool  Use nullptr instead of null or NULL  Signed and unsigned types  signed types are the same  unsigned types double the max value, but can't represent negative numbers  Need a specific number size?  First #include <cstdint>  Then use std::u?int(8|16|32|64)_t
  • 9. typedef and typeid #include <cstdint> #include <iostream> #include <typeinfo> // ^ Must include typeinfo to use the typeid operator typedef std::uint8_t byte; // Declares another name for the same type // Syntax: // typedef existing_type new_name; using std::cout; using std::endl; int main() { std::uint8_t a = 5; byte b = a; // Totally okay; the distinction is compile-time only cout << typeid(std::uint8_t).name() << endl; cout << typeid(byte).name() << endl; // Both printouts will be implementation-defined, but identical /* Common standard typedefs: size_t: Sizes of objects (usually an unsigned int) ptrdiff_t: Difference between pointers (usually an unsigned int or long) std::string: Convenient form of std::basic_string<char> */ }
  • 10. Declaring Variables #include <string> #include <vector> using std::string; using std::vector; int main() { string empty; // default constructor string empty2(); // default constructor with parens string value = "I'm really a char*"; string value2("Parens are fine, too"); string copy = value; // This is a COPY; NOT A REFERENCE string& ref = value; // THIS is a reference const string& constref = value; // A reference whose object can't be modified // All of an object's members are initialized! string* ptr; // Unassigned pointer; not necessarily nullptr vector<int> ints = {1, 2, 3, 4, 5, 6}; // You can initialize collections this way }
  • 11. Undefined behavior  Whenever something happens in Java, you can rely on something else to happen  C++ lets the compiler do anything it wants in certain situations  For performance reasons, mostly  Many, many ways to do this  Do not rely on undefined behavior
  • 12. Common undefined behaviors #include <string> #include <cstdint> #include <limits> int32_t something(int32_t param) { if (param > 0) return param; // No return down here; now what? } std::string& returnsALocal() { std::string reference = "Why are you doing this"; return reference; // Uh-oh } int main() { int32_t a = std::numeric_limits<int32_t>::max(); a++; // Oops int32_t* pointer; // Could be nullptr, could be garbage int32_t number = *pointer; // BAD int32_t[10] array; number = array[12]; // WTF }
  • 13. namespace #include <iostream> #include <string> #include <array> #include <utility> using namespace std; // ^ Don't do this for the same reason you don't do java.util.* namespace sbcs { // Nest them as much as you'd like namespace cse380 { struct Game { string name; string teamName; array<string, 3> members; }; } namespace cse381 { typedef pair<string, string> Team; } } int main() { sbcs::cse380::Game game; // Fully-qualified type name using sbcs::cse381::Team; // Or use it in the current namespace (global in this case) Team team("Jesse", "Karl"); }
  • 14. The Preprocessor #include <iostream> // Use <angle_brackets> for standard library/third-party code, "quotes" for your own #define DEBUG // You can also add #defines through your build system (e.g. the command line or // your Visual Studio project file) // #define WINDOWS // #define MAC // ^ Uncomment one of these using std::cout; using std::endl; int main() { #ifdef DEBUG cout << "Logging! Or sanity checking!" << endl; #endif #ifdef WINDOWS cout << "Use DirectX!" << endl; #else cout << "Use OpenGL!" << endl; #endif #ifdef MAC #error "Jesse doesn't like Apple" // ^ Intentionally causes a compiler error #endif }
  • 15. assert/static_assert #include <cassert> #include <type_traits> // #define NDEBUG // ^ Uncomment this or define it in the build system to disable asserts using std::is_base_of; using std::is_same; template<class T, class U> void failIfUnrelated() { static_assert( is_base_of<T, U>::value || is_base_of<U, T>::value || is_same<T, U>::value, "Both types should be the same, or one should be a parent of the other" ); } class Parent {}; class Child : public Parent {}; int main() { assert(1 + 1 == 2); assert(true && "Idiom for providing informative text in an assert()"); failIfUnrelated<int, int>(); // Okay failIfUnrelated<int, float>(); // Causes a compiler error, as desired failIfUnrelated<Parent, Child>(); // Okay }
  • 16. enum #include <iostream> using std::cout; using std::endl; enum class Direction { North, South, East, West, // Trailing comma is okay }; // NOT OBJECTS; just ints with some compile-time meaning enum class Speakers { Mute = 0, // Assigning values is okay Mono = 1, Stereo = 2, Surround = 4 }; int main() { Direction dir = Direction::North; Speakers audio = Speakers::Stereo; audio = Speakers(4); // Make sure int is a valid Speakers value! cout << int(audio) << endl; // int <-> enum class conversions must be explicit }
  • 17. Pointers #include <string> using std::string; int main() { string a = "I'm a little teapot"; string* ptr = &a; // &some_object returns the address of some_object string b = *ptr; // *some_pointer dereferences int ints[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // Raw arrays are pointers int* int_ptr = ints; // Points to ints[0] int* int_ptr2 = ints + 1; // Points to ints[1] // Increments the address sizeof(int) bytes int** double_array = &int_ptr; // Pointers to pointers okay; never usually need more than two** void* pointer_to_anything = ints; // Pointer to arbitrary data; very error-prone and unsafe; avoid unless you know // exactly why you need one pointer_to_anything = nullptr; // nullptr == Java's null; assignable to any pointer type, but not to objects float* garbage; // Uninitialized pointer; value is undefined // Could be garbage, could be nullptr; initialize it ASAP! }
  • 18. References #include <string> #include <iostream> using namespace std; // Only for slide space constraints class StringHolder { public: StringHolder(const string& str) : _str(str) {} const string& getStringReference() const { return this->_str; } string getStringCopy() const { return this->_str; } void append(const string& str) { this->_str += str; } // ^ Passes an unmodifiable reference rather than a copy private: string _str; }; int main() { StringHolder holder("France"); const string& a = holder.getStringReference(); string b = holder.getStringCopy(); cout << (a == b) << endl; // True; comparing object values cout << (&a == &b) << endl; // False; different addresses, different objects holder.append(b); cout << holder.getStringReference() << endl; // FranceFrance }
  • 19. Pointers Vs. References (Similarities)  Access large objects without copying them  Left dangling (invalid) if the referenced object is deallocated  No way to check for this  Will likely cause a crash if you try to use it  Both can point to an instance of the given type's superclass  Both compiled to similar machine code  Multiple pointers/references can refer to one object
  • 20. Pointers Vs. References (Differences)  Can represent absence of data  More prone to becoming invalid  Syntax needed to convert between pointers and objects  Can be assigned to different objects  Always initialized with a valid object  No syntax needed to use references aside from declarations or method signatures  Always points to one location in memory  Easier to deal with objects that shouldn't change
  • 21. new/delete #include <string> using std::string; void wasteMemory() { string stack_allocated = "I disappear when I go out of scope"; string* wasted = new string( "I only disappear when explicitly deallocated" ); string* cleaned = new string("I'm about to get cleaned up properly"); delete cleaned; } int main() { for (int i = 0; i < 10000; i++) { wasteMemory(); } // stack_allocated disappeared when wasteMemory() returned // All instances of wasted are still in memory // cleaned disappeared when "delete cleaned;" was called // See: Scope vs. Lifetime }
  • 22. Exceptions #include <iostream> #include <string> #include <exception> #include <array> using namespace std; // Again, slide space constraints int main() { array<int, 5> ints = {1, 2, 3, 4, 5}; try { cout << ints.at(10) << endl; // at() checks bounds, operator[] doesn't } catch (const out_of_range& e) { // You can (and should) catch by reference cout << "Out of range in an array" << endl; } catch (const runtime_error& e) { cout << "Didn't see this coming: " << e.what() << endl; } catch (const exception& e) { cout << "Unknown exception: " << e.what() << endl; } catch (...) { cout << "WTF?" << endl; } // There is no finally clause; use destructors to guarantee exception safety }
  • 23. Declaring Classes // public/protected/private semantics same as in Java // no specifier == private in classes, public in structs class ItHoldsThings { public: int cantBeOverridden(int a, int b) { // Technically you can, but things get weird return this->_integer + b; } virtual float canBeOverridden(const double d) { // virtual == overrideable return d * 2; } virtual void abstractMethod() = 0; protected: float _number; private: int _integer; }; // Don't forget the semicolon // When a class is constructed, ALL of its members are too
  • 24. Constructors #include <string> using std::string; class StringWrapper { public: StringWrapper() { /* other code here */ } // _str == "" // Default constructor can be auto-generated with some caveats (see the wiki) StringWrapper(const string& value) : _str(value) {} // _str == value // Copy constructor can be auto-generated (but see wiki) // Base class constructors are called like this, too private: string _str; // All members are initialized on construction, whether you like it or not }; int main() { StringWrapper a; StringWrapper b("There will be a copy of me in c"); StringWrapper c(b); }
  • 25. // Using constructors to allocate resources and destructors to clean them up is // called Resource Acquisition Is Initialization (RAII). Only needed for low-level // resources; high-level classes like std::iostream do RAII themselves. #include <cstdlib> using std::malloc; using std::free; class LotsOfResources { public: LotsOfResources() { _floats = new float[64]; _buffer = malloc(64); } ~LotsOfResources() { // Called when this object's lifetime ends delete[] _floats; // Remember the [] when deleting a raw array free(_buffer); } private: float* _floats; void* _buffer; }; int main() { LotsOfResources* resources = new LotsOfResources; delete resources; // No memory leaks! } Destructors
  • 26. Abstract Classes/Inheritance #include <exception> #include <iostream> // There are no interfaces; use abstract classes without any concrete methods struct ProgramCrasher { virtual void crash() = 0; // "= 0" means the method is abstract // virtual == method can be overridden // only one abstract method needed to define a class as abstract }; struct IPastryChef { virtual void bake() = 0; }; struct SegfaultCrasher : public ProgramCrasher { // Actually several types of inheritance; it's complicated, just use public void crash() override { int* a; int b = *a; } }; // Multiple inheritance; don't do it if more than one parent class is not an interface struct ExceptionCrasher : public ProgramCrasher, public IPastryChef { void crash() override { throw std::exception(); } void bake() override { std::cout << "This is just my day jobn"; } };
  • 27. (static|dynamic)_cast #include <iostream> #include <string> using namespace std; // Slide space constraints struct Base { virtual ~Base() {} string baseMethod() { return "base"; } }; struct Derived: Base { virtual string derivedMethod() { return "derived"; } }; int main() { Base* b1 = new Derived; Derived* d1_s = dynamic_cast<Derived*>(b1); cout << d1_s << ' ' << d1_s->baseMethod() << ' ' << d1_s->derivedMethod() << endl; // Checking at runtime that you're casting to the right type Derived* d1_d = static_cast<Derived*>(b1); cout << d1_d << ' ' << d1_d->baseMethod() << ' ' << d1_d->derivedMethod() << endl; // Static (compile-time) downcasts are OK (and faster) if you know you're // casting to the right type Base* b2 = new Base; Derived* d2_d = dynamic_cast<Derived*>(b2); cout << d2_d << endl; // Cast was not valid, so dynamic_cast returned nullptr // If it were a reference, it would've thrown std::bad_cast Derived* d2_s = static_cast<Derived*>(b2); // cout << d2_s << ' ' << d2_s->baseMethod() << ' ' << d2_s->derivedMethod() << endl; // ^ This is undefined, since the cast is wrong (and not checked at runtime) delete b1; // Remember to clean up! delete b2; }
  • 28. Templates #include <string> #include <vector> template<class T> class Value { public: Value(const T& data) : _data(data) {} const T& getData() { return this->_data; } private: T _data; }; // Templates are used A LOT in the standard library using std::string; using std::vector; int main() { Value<string> str("My name is Beavis"); Value<vector<int>> ints({1, 2, 3, 4, 5, 6}); // Two different classes, with two different bits of machine code }
  • 29. Templates #include <iostream> #include <array> #include <vector> #include <string> using namespace std; // Slide space constraints template<class T> void printIt(const T& object) { cout << object << endl; } template<class Container> void needsABeginMethod(Container& container) { auto iterator = container.begin(); // The begin() method returns an iterator } int main() { printIt(42); // Type parameters in function templates are usually inferred printIt<float>(7.3); // You can specify them explicitly if you need to array<int, 3> ints = {1, 2, 3}; vector<int> vec = {5, 6, 7, 8, 9}; string str = "Strings are containers"; needsABeginMethod(ints); needsABeginMethod(vec); needsABeginMethod(str); // needsABeginMethod(47); ERROR: ints don't have such a method }
  • 30. Templates #include <array> #include <iostream> #include <typeinfo> #include <string> using namespace std; // slide space limits template<class T, int ArrayLength = 10> class SomeTypedefs { public: SomeTypedefs() = delete; // Prevent instantiation typedef T Type; typedef T* Pointer; typedef T& Reference; typedef T RawArray[ArrayLength]; typedef array<T, ArrayLength> STLArray; }; // The standard library does this a lot ^ int main() { cout << typeid(SomeTypedefs<int>::Type).name() << endl; cout << typeid(SomeTypedefs<float>::Pointer).name() << endl; cout << typeid(SomeTypedefs<string>::Reference).name() << endl; cout << typeid(SomeTypedefs<int, 14>::RawArray).name() << endl; cout << typeid(SomeTypedefs<double, 3>::STLArray).name() << endl; }
  • 31. const #include <string> using std::string; const int SOME_CONSTANT = 34; const string ANOTHER_CONSTANT = "More type-safe than macros!"; class ConstStuff { public: int getData() const { // The method doesn't modify the object return this->_data; } const string& getText() const { // Gives you an immutable reference to _text; you must assign it to // a const std::string& if you don't want to copy it return this->_text; } void concatenate(const string& str) { // str itself can't be modified, and it's not copied this->_text += str; } private: int _data; string _text; }; // Attempting to violate const-correctness through runtime tricks is UB
  • 32. Operator Overloading #include <iostream> using std::cout; using std::endl; using std::ostream; // cout is an ostream struct Vector2 { float x, y; Vector2(const float x, const float y) : x(x), y(y) {} Vector2 operator+(const Vector2& other) { return Vector2(x + other.x, y + other.y); } }; // This is how most types in the standard library are printed out ostream& operator<<(ostream& out, const Vector2& v){ return out << '[' << v.x << ", " << v.y << ']'; } int main() { Vector2 a(1, 2); Vector2 b(2, 1); Vector2 c = a + b; cout << c << endl; }
  • 33. Strings to numbers and back #include <string> #include <cstdlib> using std::string; using std::stoi; using std::stol; using std::stoll; using std::size_t; // sto(i|u?ll?|f|l?d) is available using std::to_string; // to_wstring is available too int main() { int a = stoi("42"); // a == 42 long b = stol(" 0x09", nullptr, 16); // Strips whitespace, reads as base 16 // b == 9 size_t first_nonnumeric_char_index; long long c = stoll("12lbs", &first_nonnumeric_char_index, 0); // c == 12, first_nonnumeric_char_index == 2 // base-0 means assume either base 8, 10, or 16 depending on the prefix string back = to_string(c); // 12 }
  • 34. Data Structures ● The usual suspects ● You must #include <class_name> ● Prefer std::array<SomeType, Length> to SomeType[Length] ● std::vector<T> ↔ java.util.ArrayList<T> ● std::deque<T> ↔ java.util.ArrayQueue<T> ● std::list<T> ↔ java.util.LinkedList<T> ● std::set<T> ↔ java.util.TreeSet<T> ● std::map<T, U> ↔ java.util.TreeMap<T, U> ● std::unordered_set<T> ↔ java.util.HashSet<T> ● std::unordered_map<T, U> ↔ java.util.HashMap<T, U> ● std::stack<T> ↔ java.util.Stack<T> ● std::priority_queue<T> ↔ java.util.PriorityQueue<T>
  • 35. Random numbers #include <iostream> #include <random> using std::cout; using std::default_random_engine; using std::endl; using std::normal_distribution; using std::random_device; int main() { random_device seed; default_random_engine random(seed()); // Seed the generator with a totally random number (as opposed to // something like the system time) normal_distribution<float> normal(0, 1); // mean == 0, stddev == 1 for (int i = 0; i < 100; ++i) { cout << normal(random) << ' '; // Use seed instead of random if you REALLY want randomness // (but that will be slower) } cout << endl; }
  • 36. String Concatenation #include <iostream> #include <sstream> #include <string> #include <iomanip> using std::string; using std::stringstream; using std::cout; using std::endl; using std::setprecision; int main() { float x = 5.6435221, y = 7.1453634545, z = -23.452354215; stringstream coords; coords << "DEBUG LOGn" << "tPosition: [" << setprecision(4) << x << ", " << y << ", " << z << "]n"; cout << coords.str() << endl; // Use stringstream for formatted output like in debug consoles // Small amounts of pre-existing strings can be appended with operator+ }
  • 37. Iterators #include <array> #include <string> #include <iostream> using std::array; using std::cout; using std::endl; using std::string; int main() { array<string, 5> strings = {"France", "Spain", "China", "America", "Sweden"}; // No iterators for (int i = 0; i < strings.size(); i++) { cout << strings[i] << ' '; } cout << endl; // The clunky way for (array<string, 5>::iterator it = strings.begin(); it != strings.end(); it++) { cout << *it << ' '; } cout << endl; // The C++11 way for (const string& s : strings) { cout << s << ' '; } cout << endl; }
  • 38. Anonymous Functions and <algorithm> #include <array> #include <iostream> #include <algorithm> #include <functional> using namespace std; // For slide space int main() { array<int, 10> ints = {5, 7, 1, 2, 3, 9, 2, 1, 4, 2}; function<bool(int)> isEven = [](int n) -> bool { return n % 2 == 0; }; // () can be omitted if there are no parameters function<void(void)> printInts = [&ints] { for (int i : ints) { cout << i << ' '; } cout << endl; }; printInts(); // return type can be omitted if it can be deduced transform(ints.begin(), ints.end(), ints.begin(), [&isEven](int i) { // [&something] captures something by reference, [something] by value return isEven(i) ? i : i * 2; }); // ^ Doubles all odd numbers printInts(); }
  • 39. Time #include <chrono> #include <iostream> #include <thread> using std::cout; using std::endl; using std::this_thread::sleep_for; using std::chrono::duration; using std::chrono::duration_cast; using std::chrono::system_clock; typedef duration<float> secondsf; // Seconds, represented as a float // Standard typedefs for seconds, milliseconds, hours, etc. exist, too const int FPS = 60; int main() { secondsf ms_per_frame(1.0 / FPS); system_clock::time_point start = system_clock::now(); for (int i = 0; i < 300; i++) { sleep_for(ms_per_frame); cout << "Frame #" << i << endl; } cout << "Elapsed time: " << duration_cast<secondsf>(system_clock::now() - start).count() << " secondsn"; }
  • 40. Next Week  Compiling and linking code  Using Visual Studio  Overview of popular C++ tools  Building and using Box2D  This is part of your homework!