02 CPP
02 CPP
C++
Intro to C++
Differences
main() Preprocessor
#include
main()
Not a part of any class
called a function
Preprocessor
Examples
#include <iostream> // System file #include ListNode.h // user-defined file
2. Compile resulting file 3. Link the resulting files from Step 2 (more on this later)
using Directive
Similar to Javas import
Allows the programmer to not have to type the full class name
// C++ #include <iostream> using namespace std; int main() { cout << Hello World! << endl; return 0; } // C++ #include <iostream> int main() { std::cout << Hello World! << std::endl; return 0; }
10
I/O
Basic I/O
// use iostream library #include <iostream> using namespace std; int main() { int x; cout << Enter a value for x: ; cin >> x; return 0; }
11
bool
12
if ( i )
This is valid
13
14
Compiler choice
In the past we have used g++
From GNUs Compiler Collection
Consider:
speling mistake!
#include <iostream> using namespace std; int main() { cotut << "Hello World"; return 0; }
15
g++:
Error comparison
clang:
16
Functions
Functions
Methods not member of a class
#include <iostream> using namespace std; ret_type func_name(int a, int b, ) { <function body> } int main() { z = func_name(x,y, ) return 0;}
18
Function Prototypes
C++ compiler process files top to bottom
order of appearance matters without a function prototype
20
Example
// prototype
int main(){ int x=37; int y=52; cout << max(x,y) << endl; return 0; } // actual function implementation int max(int a, int b) { return (a>b) ? a : b; }
21
Classes
Java IntCell.java
public class IntCell { public IntCell() // default constructor { this(0); } // one parameter constructor public IntCell(int initialValue) { storedValue = initialValue; } // accessor member function public int getValue() { return storedValue; } // mutator member function public void setValue(int val) { storedValue = val; }
23
Java IntCell.java
// private data member private int storedValue; // main() public static void main(String [] args) { IntCell m1 = new IntCell(); IntCell m2 = new IntCell(37); System.out.println(m1.getValue() + + m2.getValue()); } }
24
26
int IntCell::getValue( ) const { return storedValue; } void IntCell::setValue( int val ) { storedValue = val; } int IntCell::max(int m){ return 1; }
28
30
Separate Compilation
Java source
Java Compiler
preprocessed files
Compiler
object files
JVM
Machine language
Linker
executable file
Machine language
31
2. Create .cpp file containing member function implementations 3. Create .cpp file containing main()
33
Reminders
1. int main() 2. Input/Output
#include <iostream> using namespace std; cout << varName << << endl;
3. Class syntax
public and private sections semi-colon at the end of class declaration ClassName::
34
35
#ifndef RATIONAL_H #define RATIONAL_H class Rational { public: Rational(); // default constructor ~Rational(); // destructor Rational(int numerator, int denominator); void print() ; Rational times(Rational b); Rational plus(Rational b); Rational reciprocal(); Rational divides(Rational b); private: int num; // the numerator int den; // the denominator int gcd(int m, int n); }; #endif
Rational.h
36
Rational.cpp
#include "Rational.h" #include <iostream> using namespace std; // default constructor: initialize to 0/1 Rational::Rational() : num(0), den(1) { } void Rational::print() { if (den == 1) { cout << num << "" << endl; } else { cout << num << "/" << den << endl; } }
37
Rational.cpp
Rational Rational::times(Rational b) { return Rational(num * b.num, den * b.den); }
38
Rational.cpp
Rational::Rational(int numerator, int denominator) { if (denominator == 0) { cout << "Denominator is zero" << endl; } int g = gcd(numerator, denominator); num = numerator / g; den = denominator / g; }
39
TestRational.cpp
#include "Rational.h" int main() { Rational x, y, z; // 1/2 + 1/3 = 5/6 x = Rational(1, 2); y = Rational(1, 3); z = x.plus(y); z.print(); // other code very much like above }
40
.h vs. .cpp?
C++ naming convention
.h // header files
function prototypes class definitions macro definitions
Pre-processor
Preprocessing
#include
Direct copy of file specified to location specified In general, only #include .h files.
#ifndef
if not defined other preprocessor directives: #ifdef, #if
#define
Defines a macro (direct text replacement) #define TRUE 0 if(TRUE == 0) {} #define _MY_OBJECT_H
#endif
specifies the end of any #if
43
#define
Can define a constant
#define PI 3.14159 area = PI * r * r;
even.h:
#include odd.h bool even (int x);
45
even.h:
#ifndef EVEN_H #define EVEN_H #include odd.h bool even (int x); #endif
46
Pointers
Pointer Variables
Stores a memory address of another object
Can be a primitive type or a class type
48
Examples of Pointers
int * x; // pointer to int char *y; // pointer to char Rational * rPointer; // pointer to Rational
49
50
C++ Syntax: *
Asterisk *
In a definition
defines pointer type
int *x
In an expression
dereferences evaluates object to which the pointer points
*x = 2
51
In an expression
address of
x = &y
52
Pointer Variables
x
Address 1000 1 int x = 1; int y = 5; int * x_pointer = &x; cout << x_pointer; cout << *x_pointer;
1004
1008 1012 1016
1000
x_pointer
53
x_pointer = &x
address
* dereferences x_pointer
54
*x_pointer = 2;
12FF x_pointer
12FF60
55
*x_pointer = 2
56
x_pointer = &y
Address x 12FF60 y 12FF54 2 5
x_pointer = &y;
address of
12FF
12FF 12FF x_pointer
12FF60 12FF54
57
x_pointer = &y
58
*x_pointer = 3
Address x 12FF60 y 12FF54 2 5 3
*x_pointer = 3;
dereference x_pointer
12FF
12FF 12FF x_pointer
12FF54
59
61
62
swap()
void swap(int * x, int * y) { int temp = *x; *x = *y; *y = temp; }
65
Calling swap()
int main() { int a=0; int b=3; cout << "Before swap(): a: " << a << "b: " << b << endl; swap(&b,&a); cout << "After swap(): a: " << a << "b: " << b << endl; return 0; }
66
68
69
Dynamic Arrays
int main() { int n; // read in a value from the user cout << "Please enter an integer value: " ; cin >> n; // use the user's input to create an array of int using new int * ages = new int [n];
70
// use a loop to prompt the user for (int i=0; i < n; i++) { cout << "Enter a value for cin >> ages[i]; } // print out the contents of the for(int i=0; i<n; i++) { cout << "ages[ " << i << " }
array
// finished with the array //clean up the memory used by calling delete delete [] ages; return 0; }
71
Output
72
73
Memory Management
Java is garbage collected
Allocated memory is automatically reclaimed, programmer does not need to think about it
delete []
delete [] ages
75
delete
#include <string> using namespace std; int main() { string * pointerToString = new string(hi); // some code that uses pointerToString here delete pointerToString; return 0; }
76
Remember this
Anything allocated with new MUST be deallocated with delete
77
For a pointer, dereference it first (as *r is the object, and r is the pointer):
Rational *r = new Rational(); (*r).num = 4;
A shorthand for the last line is below (the arrow means follow the pointer):
r->num = 4;
78
When they are deleted, how does C++ know how much memory to free up?
79
int main() { cout << "sizeof(int): " << sizeof(int) << endl; cout << "sizeof(Foo): " << sizeof(Foo) << endl; Foo *foo = new Foo(); Foo *bar = new Foo(); cout << "1st Foo: " << foo << endl; cout << "2nd Foo: " << bar << endl; int diff = ((int)bar)-((int)foo); cout << "Difference: " << diff << endl; delete foo; delete bar; return 0;
80
Associativity of *
Consider:
char* x, y;
We can all agree that x is a character pointer (32 bits) But what type is y?
Its a regular char (8 bits)
From lab 2
83
friend
Sometimes other classes need access to private data members of another class class ListNode { Why not just write accessor functions? public: // private: ListNode *next, *previous;
friend class List;
};
84
Common mistakes
Consider a class Foo with an uninitialized ListNode* field list that needs to be initialized in the constructor. What is wrong with the following two methods?
They both compile just fine
85
References
References
Declaring a reference
List sampleList List & theList = sampleList;
Reference to a List object What is a reference?
Like a pointer, it holds an address, BUT 1. Its address cannot change (its address is constant) 2. It MUST be initialized upon declaration (cannot be initialized to NULL normally) 3. Has implicit dereferencing int *x = NULL; int &y = *x;
87
Dereferencing is implied with each use All Java non-primitive types are references
89
91
92
93
*
pointer to
&
reference to
Statement dereference
o1->method()
address of
Parameter Passing
Call By Value
Actual argument is copied into formal parameter int max(int a, int b); void swap (int * x, int *y); bool compare(Rational left, Rational right);
97
Call By Reference
Pass references as parameters void swap (int &x, int &y);
Use when formal parameter should be able to change the value of the actual argument
98
100
Return Passing
Return by value
return a copy (possibly a copy of the pointer)
Return by reference
return a reference
101
Review
Review
Dynamic Memory Allocation
new
Allocates a new memory location for use Example:
Square * ptrToAnotherSquare = new Square(5); Triangle *ptrToTriangle = new Triangle(); Circle *ptrToCircle = new Circle;
delete
Reclaims memory allocated with new Example:
delete ptrToAnotherSquare;
Reclaims the memory location that was allocated, NOT the pointer. The pointer may be reassigned
103
Review
Call by value
actual argument is copied into formal parameter Example: int max(int x, int y); Use when parameters Call by reference wont need Passes references to change Example:
void swap(int & a, int & b){/* body */} int main() Function needs { to be able to int x = 1; change actual int y = 2; argument swap(x, y); // passed by reference return 0; }
104
Review
Call by constant reference
Passes references where function may not change the actual arguments Example:
bool greaterThan(const Rational & a, const Rational & b); Use for large int main() objects where { no changes will Rational x(1,2); occur. Rational y(3,4); Saves copy time bool result = greaterThan(x,y); and space. return 0; }
105
107
Destructors
Called whenever an object
goes out of scope, or delete is called
108
Copy Constructor
Special constructor that creates a new object, initialized to a copy of the same type of object Called in the following situations:
declaration with initalization
IntCell copy = original; IntCell copy(original);
operator=
aka copy assignment operator Intended to copy the state of original into copy Called when = is applied to two objects AFTER both have previously been constructed
IntCell original; // constructor called IntCell copy; copy = original; // operator= called
110
class test { static int idcount; test.h const int id; int value; public: test(); test(int v); test(const test& x); ~test(); test& operator=(const test& other); friend ostream& operator<<(ostream& out, const test& f); }; 112
int test::idcount = 0;
test.cpp 1/2
test::test() : id (idcount++), value(0) { cout << "calling test(); object created is " << *this << "; address is " << this << endl; } test::test(int v) : id (idcount++), value(v) { cout << "calling test(" << v << "); object created is " << *this << "; address is " << this << endl; } test::test(const test& x) : id(x.id), value(x.value) { cout << "calling test(&test) on " << *this << "; address is " << this << endl; }
113
test.cpp 2/2
test::~test() { cout << "calling ~test() on " << *this << endl; } test& test::operator=(const test& other) { cout << "calling operator=(" << other << ")" << endl; test *tmp = new test(other); return *tmp; }
ostream& operator<<(ostream& out, const test& f) { out << "test[id=" << f.id << ",v=" << f.value << "]"; }
114
115
-------------------------------------- calling test(); object created is test[id=0,v=0]; address is 0xff852a50 created aa: test[id=0,v=0]
116
117
118
119