📌 Const
📌 The const keyword
- We tell the complier we never intend to modify something, and it keeps us honest.
const int x = 1;
x++;
- const is a type qualifier
- const forbids assignment
- Initialization: OK (first value)
- Assignment: NOT ALLOWED!
📌 const pointers
- const pointers are a little tricky...
const int *x = &y;
- Does this mean that we can't change pointer itself, or the object (integer) it points to?
- The general rule is:
- The
const
keyword refers to whatever data type is to its left
- UNLESS there is nothing to its left, in which case it refers to whatever on its right
const int *x = &y;
x = nullptr;
*x = 0;
📌 const conversions
- You can point
const
pointers to non-const objects, but not vice versa
- Setting a
const
pointer to point at a non-const object does not change the object to be const📌 Streams
- An abstraction that allows you to read / write data from input / output
📌 File I/O with Streams
- In C++, we can read and write files directly with ifstream and ofstream objects
#include <fstream>
ifstream
and ofstream
allow you to...
- ...read a file just like reading from
cin
- ...write to a file just like printing to
cout
📌 File Output: ofstream
📌 Kinds of Objects in C++
- Atomic
- Also known as primitive
- int, double, char, etc
- Pointer types
- Arrays (homogeneous)
- An contiguous sequence of objects of the same type
- Class-type (heterogeneous)
- A compound object made up of member subobjects.
- The members and their types are defined by a struct or class
📌 Compound objects
- We often have several objects that are related to one another
- Rather than declaring them all separately (duplicate code, harder to read), combine them all together in a single, composite object
- We can use both
struct
and class
to create class-type objects in C++.
- We'll focus on
struct
for now.
📌 Initializing structs
- you can use an initializer list to initialize each member of a
struct
- You can do this for assignment, unlike with an array.
Demo: Person_birthday
- Let's create a function that updates a person's age when they have a birthday
void Person_birthday(Person p) {
}
This is doomed for failure.. why?
- We have to pass using apointer or pass-by-reference in order to avoid the copy
void Person_birthday(Person *p) {
(*p).age += `;
if ((*p).age > 18) {
(*p).isNinja = true;
}
}
void Person_birthday(Person &p) {
p.age += 1;
if (p.age > 18) {
p.isNinja = true;
}
}
📌 The Arrow Operator
- Use the -> operator as a shortcut for member access through a pointer
📌 Passing structs as parameters
- You usually don't want to pass by value.
- Usally don't need to copy the struct.
void func(Person p);
- If you intent to modify the outisde object, pass by pointer or reference.
void func(Person *p);
void func(Person &p);
- Otherwise, pass by pointer-to-const or reference-to-const. (Safer and more effiencient than by value.)
void func(Person const *p);
void func(Person const &p);