0% found this document useful (0 votes)
43 views

Week 1 Slides

Uploaded by

Tic Cevm
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
43 views

Week 1 Slides

Uploaded by

Tic Cevm
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 58

First steps

1
The minimal C++ program
int main() {
return 0;
Not inside a class
} ●

● main() returns an int

‘exit code’
● No ‘String[] args’

2
Hello, World!
#include <iostream>

int main() {
std::cout << "Hello, World!\n";
return 0;
}
g++ -std=c++11 -o hello hello.cc
./hello 3
There is no JVM
● The compiler produces an executable
– hello on Linux or OS X
– hello.exe on Windows

● Runs directly on the OS, which can improve


performance
– Useful for performance-critical systems (networking,
finance, gaming, engine management computers, robotics
with low-power CPUs, ...)

4
The answer to life, the universe &
everything
#include <iostream>
using std::cout;
using std::endl;

void printAnswer(int x) {
cout << "The answer to life the universe "
<< "and everything is " << x << endl;
}

int main() {
printAnswer(42);
}
5
Function prototypes
int answer();

int main() {
printAnswer(answer());
}

int answer() {
return 42;
}

6
For now, use std::vector for arrays
#include <vector>
using std::vector;

int main() {
vector<int> numbers(10);
for (int i = 0; i < 10; ++i) {
numbers[i] = i;
}
numbers.resize(20);
...

7
}
std::string
● Based on a vectors of characters
#include <string>
using std::string;
...

int main() {
string a = "And";
string b = "rew";
string c = a + b;

c[5] = i;

cout << c << endl;


}
8
Writing files in C++
#include <fstream>
using std::ofstream;

void writeHello() {
ofstream writer("filename.txt");
writer << "Hello disk\n";
}

9
A quick warning (i)
● Java default initialises primitive values
– e.g. int values default to 0
● C++ does not – can get ‘interesting’ bugs from using uninitialised values
int x;
if (x > 1000000) { // could be true
// or false

...do something important...


}
10
A quick warning (ii)
● There’s no
ArrayIndexOutOfBoundsException
● Take care not to read off the end of a vector

11
Objects: The Basics

12
Simple objects
class Coordinate {
● class – not public class
● Access specifier sections
protected:
● Initialisation syntax
int x;
constructor
int y;

public:
Coordinate(int xIn, int yIn)
: x(xIn), y(yIn) {
}
13
};
c.w. Java-style constructor
Coordinate(int xIn, int yIn)
: x(xIn), y(yIn) {
}

Coordinate(int xIn, int yIn) {


x = xIn;
y = yIn;
}

14
Making objects
int main() {
● No new – a and b are
Coordinate a(4,-3); Coordinates
Coordinate b = a;

cout << a.getX() << endl;


cout << b.getX() << endl;

a.setX(8);
cout << a.getX() << endl;
cout << b.getX() << endl;
15
}
Copying objects
Coordinate a(4,-3);
Coordinate b = a;

● Create Coordinate a; constructor gets (4,-3)


● Create Coordinate b, using an automatically generated copy

constructor that copies whatever the member variable are in a


● Can write our own too (will explain later)

16
This won’t compile
int main() {

Coordinate a(4,2);
Coordinate b;

Looks for the default constructor Coordinate()


17
Implicit default constructor calls
{1} vector<Coordinate> coords(2);
{2} coords[0] = Coordinate(4,-2);
{3} coords[1] = Coordinate(3,17);

● Line {1}: make a vector of size 2. Use the default constructor for
each Coordinate.
– Only works if there is a default constructor!
● Line {2}, {3}: replace the coordinates in the vectors with these
ones anyway
18
Alternatively
{1} vector<Coordinate> coords;
{2} coords.push_back(Coordinate(4,-2));
{3} coords.push_back(Coordinate(3,17));

Line 1: make an empty vector (size 0)


Line 2: add an extra Coordinate to the vector (size now 1)
Line 3: add another (size now 2)

19
A Journey – this won’t compile!
class Journey {

protected:
Coordinate start;
Coordinate end;

public:

Journey(Coordinate startIn,
Coordinate endIn) {
start = startIn;
end = endIn;
}
}; 20
This will compile
class Journey {

protected:
Coordinate start;
Coordinate end;

public:

Journey(Coordinate startIn,
Coordinate endIn)
: start(startIn),
end(endIn) {
}
21
};
The initialisation syntax
● Whatever is put in brackets is given to the
constructor of the object
● No default constructor? We have to use it

22
Why is insisting on construction
useful?
Why might this Java code give a runtime error?

public static void printLength(String a) {


System.out.println("Length is: "
+ a.length());
}

23
Why is insisting on construction
useful?
How about this C++ code?

void printLength(string a) {
cout << "Length is: "
<< a.size()
<< endl;
}

24
It can’t give a NullPointerException

(It is possible to get them in C++,


but we can often avoid the risk.) 25
How to fail at Java
String a = new String("Dave");
String b = new String("Dave");

if (a == b) {
System.out.println("Dave is Dave");
}

26
a and b are not strings
String a = new String("Dave");
String b = new String("Dave");

if (a.equals(b)) {
System.out.println("Dave is Dave");
}

27
C++ Dave is Dave
#include <string>
using std::string;

int main() {
string a = "Dave";
string b = "Dave";

if (a == b) {
cout << "Dave is Dave\n";
}
28
}
So can we write this then?
Coordinate a(4,-2);
Coordinate b(4,-2);

if (a == b) {
cout << "They are equal\n";
}

29
Nearly
class Coordinate {
//...
public:
//...
bool operator==(Coordinate other) {
return (x == other.x && y == other.y);
}
};

30
Overloading arithmetic operators
class Coordinate {
//...
public:
//...
Coordinate operator+(Coordinate other) {
return Coordinate(x + other.x,
y + other.y);
}
};

31
Copies vs References

32
Accidentally making objects
void moveXToZero(Coordinate in) {
in.setX(0);
}

int main() {
Coordinate a(4,-3);
moveXToZero(a);

cout << a.getX() << endl;


} 33
Scope
int main() {
Coordinate a(4,-3);
→ make a Coordinate ‘a’ scoped to this function
}

void moveXToZero(Coordinate in) {


→ make a Coordinate ‘in’ scoped to this function, set
to a copy of whatever is passed as the argument
34
Pass by reference
void moveXToZero(Coordinate & in) {
in.setX(0);
}

in is a reference to what is passed to the function – it’s


an alias (another name) for what was passed to the function
It doesn’t take a copy, and can’t be changed to refer to any
other object
35
References can’t be null

36
I accidentally more copies
class Journey {

private:
Coordinate start;
Coordinate end;

public:
...
Coordinate getStart() {
return start;
}

};

37
Return by reference
class Journey {

private:
Coordinate start;
Coordinate end;

public:
...
Coordinate & getStart() {
return start;
}

};

38
What will this do?
int main() {
Journey j(Coordinate(1,1),
Coordinate(10,3));

Coordinate & a = j.getStart();


a.setX(0);
getStart() returned a reference to j.start;
So a is an alias for j.start

cout << j.getStart().getX() << endl;


}

39
What about this?
int main() {
Journey j(Coordinate(1,1),
Coordinate(10,3));

Coordinate a = j.getStart();
a.setX(0);

cout << j.getStart().getX() << endl;


}

40
References can be dangerous
● Return by reference can allow member variables to be
changed from outside the class

● This is dangerous – the point of object-oriented


programming is to maintain invariants
– e.g. if journey had a variable ‘distance’ changing the distance
between ‘start’ and ‘end’, calling getStart().setX(0)
would mean the value of ‘distance’ was wrong

41
I have no idea what I’m doing

void printX(Coordinate & in) {


cout << in.getX() << endl;
in.setX(0); // YOLO
}
● Passing an object by reference might mess it up.
42
Pass by const reference:
look but don’t touch
void printX(const Coordinate & in) {
cout << in.getX() << endl;
}

43
const is constagious
class Coordinate {
//...
public:
//...
int getX() const {
return x;
}
void setX(int xIn) {
x = xIn;
}
};
44
Return by const reference
class Journey {

const Coordinate & getStart() {
return start;
}
};
Which of these [i-iv] will compile?
int main() {
Journey j(…);
Coordinate a = j.getStart(); // [i]
Coordinate & b = j.getStart(); // [ii]
const Coordinate & c = j.getStart(); // [iii]
const Coordinate d = j.getStart(); // [iv]
}
45
Operators revisited

if ( == ){

46
How can we now improve this?
class Coordinate {
//...
public:
//...
bool operator==(Coordinate other) {
return (x == other.x && y == other.y);
}
};

47
The operator== recipe
When using ‘==’ for objects of type a and b, provide one of the following:

class a {
public:
bool operator==(const b & rhs) const;
};
...or...:
bool operator==(const a & lhs, const b & rhs);

48
Functions don’t have to be in classes
● The system provides a class Alice, and you can’t change it
● Suppose you write a class Bob; then you want to write:

Alice a;
Bob b;
if (a == b) { … }

49
operator<<
Coordinate a(-4,2);
cout << "It is at " << a << endl;

50
operator<<
Coordinate a(-4,2);
cout << "It is at " << a << endl;

is really:

((cout << "It is at ") << a) << endl;

51
First attempt
void operator<<(ostream & o,
const Coordinate & rhs) {
o << rhs.getX()
<< ","
<< rhs.getY();

52
The snag...
●What happens here?
Coordinate a(4,2);
cout << a << endl;

53
The snag...
●What happens here?
Coordinate a(4,2);
(cout << a) << endl;

54
The snag...
●What happens here?
Coordinate a(4,2);
(cout << a) << endl;
calls operator<<(cout, a), which returns void

55
The snag...
●What happens here?
Coordinate a(4,2);
(cout << a) << endl;
void

56
Return ostream &
ostream & operator<<(ostream & o,
const Coordinate & rhs) {
o << rhs.getX()
<< ","
<< rhs.getY();
return o;
}

57
A two-part solution
class Coordinate {
public:
void write(ostream & o) const {
o << x << "," << y;
}
};

ostream & operator<<(ostream & o,


const Coordinate & rhs) {
rhs.write(o);
return o;
58
}

You might also like