Practice Session 3
Topics:
•
•
•
•
•
•
•
•
•
•
References
Objects - Classes
Object construction
Member Initialization List
this, ->, .
Operator= overloading
Object Destruction
Java Classes vs. C++ Classes
Inheritance
Const Revisited
makefile
the make utility
C++ Compilation Process
• Input:
– C++ Code, .h and .cpp files.
• Preprocessor:
– Removes comments
– interpreting special preprocessor directives denoted by #:
• #include <math.h> – paste in the standard library math file.
• #include "My.h" – paste in the file My.h from the same directory (relative path)
• C++ Compiler:
– Converts C++ code to Assembly code
– What is Assembler? Programming language. Lower level than C++
– Example code: http://www.assembly.happycodings.com/code1.html
• Assembler:
– Converts the Assembly code to object code – “.o” files. – this is machine code.
Not executable until linking is done!
• Linker:
– Takes several object code files, and links them together into an executable.
• Output: Executable file.
Why makefile?
• An advanced way to compile your
program with a single line!
• After creating the makefile ofcourse…
• But that needs to be created only once!
• Saves a lot of time.. We’ll see how…
Makefile example code
helloWorld: run.o helloWorld.o
g++ –Wall –o helloWorld run.o helloWorld.o
run.o: HelloWorld.h
g++ –c Run.cpp
helloWorld.o: HelloWorld.h
g++ –c HelloWorld.cpp
clean:
rm –rf ./*.o helloWorld
Compiling program:
Command:
make helloWorld
Process:
compiles first run.o
compiles HelloWorld.o
links run.o and helloWorld.o into
helloWorld
Removing binaries:
Command:
make clean
Process:
clean has no dependencies, so it runs
the remove command.
How the Makefile Works
• T1: D1 D2
<tab>Commands
To build T1, the make utility will work as follows:
1. if either D1 or D2 do not exist, build them (recursively).
2. Check if both D1 and D2 are up to date. If not, build them recursively.
3. Check the date of T1 (the modification time). If T1 is at least as new as
BOTH D1 and D2, we are done; Otherwise, follow the instructions given
to build T1
•
•
CC = g++
CFLAGS = -g -Wall -Weffc++
•
•
# All Targets
all: hello
•
# Executable "hello" depends on the files hello.o and run.o.
•
hello: bin/hello.o
Example from Practical
Session 2 Part B – Makefile
Segment
bin/run.o
•
•
•
•
•
@echo 'Building target: hello'
@echo 'Invoking: C++ Linker'
•
# Depends on the source and header files
•
•
bin/hello.o: src/HelloWorld.cpp include/HelloWorld.h
$(CC) $(CFLAGS) -c -Linclude -o bin/hello.o src/HelloWorld.cpp
•
# Depends on the source and header files
•
•
bin/run.o: src/Run.cpp include/HelloWorld.h
$(CC) $(CFLAGS) -c –Linclude -o bin/run.o
•
#Clean the build directory
•
clean:
$(CC) -o bin/hello
bin/hello.o
bin/run.o
@echo 'Finished building target: hello'
@echo ' '
•
src/Run.cpp
rm -rf bin/*
Reading material: http://dev-faqs.blogspot.com/2011/03/simple-makefile-tutorial.html
• When you type "make" in your shell, the script
will look for a file "makefile" in the same
directory and will execute it.
• By default, make will only execute the first target
in the makefile; so, make sure the first target will
cause a complete build.
• Important - the space you see to the left of some
lines are tabs, and not space characters.
• makefile variables are all upper-case, and are
referenced using ${VAR_NAME} or
$(VAR_NAME).
makefile example
# define some Makefile variables for the compiler and compiler flags
# to use Makefile variables later in the Makefile: $()
CC = g++
CFLAGS = -g -Wall
OBJECT_FILES = run.o imageloader.o
INCLUDE_LIBRARIES = -I/usr/local/include/opencv -I/usr/local/include
SHARED_LIBRARIES = -L/usr/local/lib
OPENCV_LIBS = -lopencv_core -lopencv_highgui
# All Targets
all: run
Comment: # All Targets
Define Variables: CC, FLAGS, …
Use Variables: $(CC), $(FLAGS)
Function definition: clean:
Function with dependencies: all: run
Dependencies mean that you run the functions that your
function depends on, then your function after.
Printing to shell: @echo ‘Building target: run’
$<: the first item in the dependencies list for this function:
1st $< is src/imageloader.cpp
2nd $< is src/run.cpp
-o $@: the output file name is the function name.
1st –o $@ is run
2nd –o $@ is imageloader.o
3rd -o $@ is run.o
# Tool invocations
# Executable "run" depends on the files imageloader.o and run.o.
run: $(OBJECT_FILES)
@echo 'Building target: run'
@echo 'Invoking: C++ Linker'
$(CC) $(CFLAGS) $(OBJECT_FILES) -o $@ $(INCLUDE_LIBRARIES) $(SHARED_LIBRARIES) $(OPENCV_LIBS)
@echo 'Finished building target: run'
@echo ' '
# Depends on the source and header files
imageloader.o: src/imageloader.cpp include/imageloader.h
$(CC) $(CFLAGS) $< -c -o $@ $(INCLUDE_LIBRARIES) $(SHARED_LIBRARIES) $(OPENCV_LIBS)
# Depends on the source and header files
run.o: src/run.cpp
$(CC) $(CFLAGS) $< -c -o $@ $(INCLUDE_LIBRARIES) $(SHARED_LIBRARIES) $(OPENCV_LIBS)
#Clean the build directory
clean:
rm -rf *.o run
Lvalue References
• A variable that is used to refer to another variable (alias).
• Notation:
varType &refVar = objVar;
• Example:
int i =3;
int &r =i;
r = 4; //will change the value of i to 4
• Hides indirection from programmer
• Must be typed (int, double…)
– Can only refer to the type to which it can point.
– Checked by compiler
int &r = i; // can only refer to int
• Must always refer to something
– Must be initialized upon creation.
– Cannot be initialized to 0 or NULL.
– Value cannot be changed once initialized.
• What are they for?
– When you send a variable to a function:
– Function: void removeLast(intArray intArr){ ... };
– intArray myArr = intArray(1,2,3,4,5);
– removeLast(myArr);
– Variable is passed by value! Which means a copy of
myArra is created and sent to the function.
– Problem?
• Functions that alter the values of the variable sent to them cannot
alter the variable! They will alter a copy of the variable.
• Possible solution?
– Alter the function to return the same object type:
• intArray removeLast(intArray intArr){ … };
• Usage:
» myArr = removeLast(myArr);
– Another solution?
• References!
– void removeLast(intArray& intArr){ … };
– Usage:
» removeLast(myArr);
• Common places references are used at?
– Used in copy constructor
– Used in operator overloading
Reference vs. Pointers
• Reference:
–
–
–
–
Referencing is done directly.
User interacts with it as if it was the object itself.
Must be typed.
Must be initialized upon creation. Can’t be altered after.
• Pointer:
–
–
–
–
Stores the memory address of the object.
Requires dereferencing in order to retrieve the object.
Does not have to be typed. (use casting..)
Does not have to be initialized upon creation. Can be altered afterwards.
Dereferencing:
• the act of getting what the pointer is pointing at.
Objects - Classes
• Classes:
– Encapsulate data (state/attributes) and methods (behavior) – protect
its data from outside modification.
– They include:
• Data (data members) –
• methods (member functions)
– In other words, they are structures + functions
• Objects:
– Entities in a software system which represent instances of real-world
and system entities.
Example: Person
Person
Object members:
name: string
address: Address
age: integer
Object methods:
setAge()
setName ()
getName()
getAge()
toString()
C++ Object Classes
• To create a new object type we need two files:
– Class.h
• declaration of class methods and variables.
– Class.cpp
• implementation of declared methods.
• Notes:
– This separation is not mandatory, but makes life much easier! (Same style as Java’s Interface/Class
separation)
– You can implement more than one class inside same .cpp file!
.h and .cpp class: example
•
• Address.cpp:
Address.h:
#ifndef ADDRESS_H_
#define ADDRESS_H
#include "Address.h"
Declarations!
#include <string>
#include <sstream>
class Address {
public:
Address();
Address(const Address &other);
virtual ~Address();
std::string toString();
Address& operator= (const Address &other);
Address* copy();
private:
int houseNumber;
std::string streetName;
std::string zipCode;
};
Address::Address() {
houseNumber = 1;
streetName = "noName";
zipCode ="30055";
}
Implementation!
Address::Address(const Address &other){
houseNumber = other.houseNumber;
streetName = other.streetName;
zipCode = other.zipCode;
}
Address& Address::operator=(const Address
&other){
houseNumber = other.houseNumber;
streetName = other.streetName;
zipCode = other.zipCode;
return *this;
}
Address::~Address() {}
#endif /* ADDRESS_H_ */
If the class is defined in the .header file.
You do not define it again in the .cpp
file! You only implement the
constructors/methods/destructor!
std::string Address::toString(){
std::stringstream sstr;
sstr << "Address: houseNumber: " <<
houseNumber << " streetName: " <<
streetName << " zipCode: " << zipCode;
return sstr.str();
}
Object Construction
• Default constructor:
– Receives nothing as input.
– Example:
• Person();
• (Regular) constructor:
– Receive parameters as input
– Example:
• Receives (name,age) as an input:
– Person(int age, string name);
• Receives name as input:
– Person(string name);
• Receives age as input:
– Person(int age);
• If you define a constructor that takes arguments, then you
need to define a default constructor as well!
Important: http://www.parashift.com/c++-faq-lite/ctors.html
Copy Constructor: Declaration
• Has one argument only: reference to the to-be-copied object
of same type.
• Reference must be const.
• Example:
– List(const List &l);
– Point(const Point &p);
– Person(const Person &p);
• Copy Constructor is called:
– Explicit Call:
Person p1;
Person p2(p1); //copy ctor called to copy p1
– Implicit Calls:
• Person p1;
Person p2 = p1; //copy constructor is called here
•
On function return:
Person getParent(Person); //the copy ctor is used to copy the
return value
•
When sending an object to a function:
getParent(p1); // copy ctor is used to copy p1
Member initialization list
• Assignment options:
– Explicit: int x = 5;
– Implicit: int x(5);
• Example:
class Person
{
private:
int age;
string name;
Address address;
public:
Person(){ age = 21; name = “hi”;}
Person(int hisAge){ age = hisAge; name = “hi”;}
Person(int hisAge) : age(hisAge), name(“joy”), address() {}
};
• member initialization list is executed before the body
of the function.
• It is possible to initialize data members inside the
constructor body but not advised:
– if a data member is itself a class object, not initializing it
via the initialization list means implicitly calling its default
constructor! If you do initialize it in the body of the
constructor you are actually initializing it twice.
• Const members - Const members of a class can only be
initialized via member initialization list.
• The order of initialization is according to the order the
member vars are declared (not the order in the
member initialization list).
Examples
•
•
Regular Assignment, using “=“ operator.
Example:
class Person{
private:
int age;
string name;
Address address;
public:
Person() {
age = 21;
name = “joy”;
Address = Address(“Beer Sheva”);
}
};
address is initialized twice!
1. before the body of the
constructor using its default ctor
2. inside the body of the ctor using
a ctor that takes a string.
Using initializing list:
Person():age(21),name(“joy”),Address(“Beer
Sheva”){};
this, -> and .
• “this”: a pointer to the currently active object.
– Example:
void setX(int x){
this->x = x;
}
• “->”: Equals to dereferencing a pointer and then using the “.” operator
– a->b is equavilant to (*a).b
– (*p).method() is equivalent to p->method()
• “.”: Used to access variables of a reference or a regular object-variable:
Person p1;
Person &p2 = p1;
Person *p3 = &p1;
std::cout << p1.getName();
std::cout << p2.getName();
std::cout << (*p3).getName();
dereference: getting the value pointed by the pointer.
The rule of 3
• For classes owning a resource. These three functions must be
implemented:
– A destructor
– A copy constructor
– A copy assignment operator (operator=)
Object Copying
Person(){
string name(“hi”)
int age = 21
Address *address =
new Address();
}
Address(){
int houseNumber =
21;
string streetName =
“j”;
string zipCode = 255;
• Shallow:
• Deep:
Person p1;
Person p2;
p2=p1 equals to:
Person p1;
Person p2(p1);
This is equals to:
p2.name = p1.name
p2.age = p1.age
p2.address = p1.address
p1.address and p2.address point at
the same memory block!
p2.name = p1.name
p2.age = p1.age
p2.address->houseNumber = p1.address>houseNumber
p2.address->streetName= p1.address-> streetName
p2.address->zipCode= p1.address->zipCode
Solves shallow copying problem.
How it is done? By overloading “=“ operator!
Copy assignment operator
•
Overloading:
•
•
Overloading provides the ability to use the same operator to perform different actions.
Example:
– Person.cpp:
Person& Person::operator=(const Person &other){
name = other.name;
age = other.age;
address = new address();
*address = *(other.address);
return *this;
}
– Address.cpp:
Address& Address::operator=(const Address &other){
houseNumber = other.houseNumber;
streetName = other.streetName;
zipCode = other.zipCode;
return *this;
}
Now when we do p2=p1, we will end up with two different variables
containing two different objects with the same values!
Futher Reading: http://www.learncpp.com/cpp-tutorial/911-the-copy-constructor-and-overloading-the-assignment-operator/
Operator = Should Do the Following:
Person & Person::operator=(const Perso
n &other) {
• check assignment to self
// check for "self assignment" and do nothing in t
hat case
if (this == &other)
return *this;
name = other.name;
age = other.age;
Address * tmp = other.address->copy();
delete(address);
address = tmp;
• copy data member from
other to a tmp variable.
• clear existing data members
• copy data member from tmp
to this->address.
• return this
// return this List
return *this;
}
Order is important if you catch exceptions, to prevent memory leaks!
Question!
• Person p1;
• Person p2;
• Person p3 = p1;
vs.
p2 = p1;
• What is the difference?
• Hint: What do they call?
• Hint:
– What calls overloaded “=“ function?
– What calls the Copy Constructor?
Person p1; implicitly calls default constructor!
p2=p1;
Person p3=p1;
Object Destruction
• Destructors:
–
–
–
–
–
Same name as class Preceded with tilde (~)
No arguments .
No return value.
Cannot be overloaded.
Mainly used to de-allocate dynamic memory locations.
– Example:
calls the destructor of Address object
• Person.h: ~Person();
• Person.cpp: Person::~Person(){ delete address; };
Public Functions
• Defining public functions:
– Using “public:” keyword.
– Accessable by the user.
– Example:
public:
Point();
Point(double xval, double yval);
void move(double dx, double dy);
double getX() const;
double getY() const;
• Functions and variables that are defined after the public notation, are accessible
by the user.
Private Functions
• Defining private variables and functions:
– Using “private:” keyword.
– Accessable only by the class itself.
– Example:
private:
double _y;
double _x;
void switch(double x, double y);
• Functions and variables that are defined after the private notation,
are not accessable by the user.
C++ Classes vs. Java Classes
1
• Declarations and implementation of class:
– Java: Stored in same file.
– C++: Separated:
• declarations: .h file
• implementation in .cpp.
• End of class:
– Java: Class ends with “}”.
– C++: Class ends with “};”.
C++ Classes vs. Java Classes
2
• Private/Public declarations:
– C++:
• Public section(Keyword: “public:”)
• Private section (Keyword: “private:”)
– Java:
• No sections! Each function contains Public/Private keyword.
Const Revisited
• const = value will not be changed.
• Refers to the word on its left; unless there’s none, then refers to the
word on its right.
• const can be used on:
– Variables:
• const int i = 5; //the value of is 5; cannot be changed!
– Pointers:
int i;
int * const j = &i;//value of j cannot be changed
int const *j = &i;//value of I cannot be changed through j
const int* j = &i; //value of I cannot be changed through j
– References:
• int i;
• const int &ref = i; // i cannot be changed through ref
– Class Methods:
• Do not change the state (fields) of an object.
class Point {
public:
…
double getX() const;
double getY() const;
void move(double dx, double dy);
private:
double _x;
double _y;
};
const Functions
• const:
– Function cannot change state of the object (compiler throws error).
– Example: (function declaration)
•
double getX() const;
• const objects can use const functions only.
• const objects cannot use regular functions
• Example:
– Functions:
• double getX() const;
• void move(double dx, double dy);
– Object:
• const Point p(0,0); //constant object p of type Pointer is created.
– Run example:
• p.getX(); //OK
• p.move(1,1); //Compilation error!
Inheritance
• C++ has 3 kinds of inheritance:
– Public - public members are accessible everywhere, within and outside the class scope
– Private - private members can be only accessed within the class and its methods
– Protected - protected members are accessible within the class and its methods and in its descendants
– Java has only one kind: public inheritance.
• Calling “super”:
ExtendedClass::ExtendedClassCtor(int val) : BaseClassCtor(val) {}
– No super keyword!
Further Reading: http://www.cplusplus.com/doc/tutorial/inheritance/
Public Inheritance
• Syntax:
: public
• Example:
class ExtendedClass : public BaseClass { … };
• All members keep their original access specifications:
– Private members stay private
– Protected members stay protected
– Public members stay public.
• Most commonly used inheritance type.
Protected Inheritance
• Syntax:
: protected
• Example:
class ExtendedClass : protected BaseClass { … };
– Public and protected members become protected
– Private members stay private.
• Almost never used.
Private Inheritance
• Syntax:
: private
• Example:
class ExtendedClass : private BaseClass { … };
– All members from the base class are inherited as private.
– Private members stay private.
– Protected and public members become private.
Futher Reading: http://www.learncpp.com/cpp-tutorial/115-inheritance-and-access-specifiers/
Classes that contain Pointers
• Every class that contains pointer variables
must include:
–A virtual destructor:
• virtual ~Person();
–A copy constructor:
• Person(const Person &other);
–Overloaded “=“ operator:
• Person& operator=(const Person &p)
Classes that contain Pointers
• Virtual destructor:
– virtual ~Person();
• Uses:
– In order to delete pointer data members and to free memory
• Why Virtual?
– Allows the correct destructor to be called upon deletion of object!
• Example:
– class Boy :public Person{ … };
– Person *p = new Boy();
– delete p;
• Non virtual destructor: ~Person() is called.
• Virtual destructor: ~Boy() is called.
• Implementation Example:
– ~Person(){ delete address);
– Note: delete address automatically, calls the address destructor.
– Equivalent to: address->~address
Classes that contain Pointers
• Copy constructor:
– Person(const Person &other);
• Uses:
– Allows deep copying.
– Allows creating copies of same object.
• Example:
– Person p1;
– Person p2 = p1;
Classes that contain Pointers
• Overloaded “=“ operator:
– Person& operator=(const Person &p)
• Uses:
– Allows deep copying. .
• Example:
– Person p1; Person p2; p2=p1;
© Copyright 2026 Paperzz