0% found this document useful (0 votes)
4 views66 pages

CMP1002 Lecture6

Lecture 6 by Erkut Arican covers the use of const objects and member functions in C++, emphasizing the importance of preventing modifications to objects through the const keyword. It explains how const member functions cannot alter object data and outlines rules for their usage, including the implications for constructors and destructors. The lecture also discusses composition, friend functions, and the use of the 'this' pointer in member functions.

Uploaded by

emironus.47
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)
4 views66 pages

CMP1002 Lecture6

Lecture 6 by Erkut Arican covers the use of const objects and member functions in C++, emphasizing the importance of preventing modifications to objects through the const keyword. It explains how const member functions cannot alter object data and outlines rules for their usage, including the implications for constructors and destructors. The lecture also discusses composition, friend functions, and the use of the 'this' pointer in member functions.

Uploaded by

emironus.47
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/ 66

CMP1002

Erkut ARICAN
Lecture 6
const (Constant) Objects and
const Member Functions
const Objects
We utilize constant objects and constant
member functions to avoid object alterations
and enforce the concept of minimal
permission.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 3


const Objects
•Certain objects may require the ability to be modified
while others may not.

•To prevent modifications to an object, the


programmer may utilize the keyword "const".

•By using "const", the programmer specifies that the


object cannot be modified, and any attempt to do so
will result in a compilation error.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 4


const Objects
•Declaring an object as const helps enforce the principle of
least privilege: This means that by using the keyword "const"
when declaring an object, you can ensure that the object
cannot be modified by any means.

•Attempts to modify the object are caught at compilation time


rather than causing execution-time errors: By marking an object
as const, the compiler will catch any attempts to modify it
before the program is run. This can help prevent runtime errors
and ensure program stability.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 5


const Objects
•Using const properly is crucial to proper class design,
program design, and coding: Using const properly and
consistently throughout a program ensures that
objects are only modified where necessary and
promotes good coding practices. Proper use of const
can also help make programs more efficient by
reducing unnecessary copying and memory allocation.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 6


Member function calls of const Objects
When an object is declared as const in C++, the
compiler prohibits calling non-const member
functions for that object. Only member functions that
are also declared as const can be called by const
objects.

Furthermore, member functions that are declared as


const are not allowed to modify the object.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 7


Member function calls of const Objects
// Define a member function named getRadius that returns the radius value of the Circle object
double getRadius() const {
return radius;
}

// Define a member function named getArea that returns the area of the Circle object
// using the formula pi * r^2, where pi is approximated as 3.14
double getArea() const {
return 3.14 * radius * radius;
}

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 8


Member function calls of const Objects
These are some rules for using const member functions in C++:

1.If a member function is declared const, it is a compilation


error to modify any object data member.

2.If a member function is declared const, it is a compilation


error to call a non-const member function of the class on the
same instance.

3.Invoking a non-const member function on a const object is a


compilation error.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 9


Member function calls of const Objects
The crucial point is that a const member function can be overloaded
with a non-const version.

When invoking a member function on an object, the compiler selects


which overloaded member function to use based on the object itself.

For example, if the object is declared const, the compiler selects the
const version of the function. On the other hand, if the object is not
const, the compiler selects the non-const version of the function. This
allows for more flexible use of member functions in different contexts.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 10


Const Constructors and Destructors
•It is not possible to declare constructors and destructors as
const in C++

•Constructors should be able to modify an object to initialize it


correctly.

•Destructors need to be able to execute any necessary clean-


up tasks before the system frees the object’s memory.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 11


Const Member Functions
Const member functions cannot alter the values of
class data members that they belong to.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 12


Member initializer list
Member initializer list
Member initializers are used to set the initial values
of class data members within a constructor.

The member initializer list comes after the


constructor's parameter list and is introduced by a
colon (:).

Each member initializer contains the name of a data


member, followed by parentheses enclosing the
initial value for that member.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 14


Member initializer list
It is possible to initialize all class data members using
member initializer syntax.

However, it is mandatory to initialize data members


that are constants or references using member
initializers.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 15


Member initializer list
#include <string>
#include <iostream>

class Student {
public:
Student(const std::string& n, int a, const std::string& m);
void print() const;
private:
std::string name;
int age;
std::string major;
const int id; // const data member
static int idCount; // static data member for generating unique IDs
};

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 16


Member initializer list
#include "Student.h"

Student::Student(const std::string& n, int a, const std::string& m)


: name(n), age(a), major(m), id(idCount++) // member initializer list
{}

void Student::print() const {


std::cout << "Name: " << name << ", Age: " << age << ", Major: " << major << ", ID: " << id <<
std::endl;
}

int Student::idCount = 1; // initialization of static data member

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 17


Member initializer list
#include "Student.h"

int main() {
Student s1("Alice", 20, "Computer Science");
s1.print();

Student s2("Bob", 21, "Mathematics");


s2.print();

return 0;
}

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 18


Member initializer list
An object declared const cannot be modified by assignment, so
it must be initialized at its creation.

If a data member of a class is declared as const, its initial value


must be provided using a member initializer in the class’s
constructor when creating an object of the class.

Similarly, when a class data member is declared as a reference,


it must also be initialized using a member initializer in the
constructor.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 19


Composition
Composition
•Including a Time object as a member of the AlarmClock class enables it to
know when to sound its alarm.

•This is an example of composition, which is a type of relationship known as


"has-a.«

•A class can have other class objects as its members.

•The relationship between the Patient and Date classes is an example of


composition, as the patient "has" a birth date.

•Similarly, the relationship between the Course and Instructor classes is an


example of composition, as the course "has" an instructor.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 21


Composition
Composition, where a class has objects of other
classes as members, is a widely used technique for
software reusability.

When an object is created, its constructor is invoked


automatically to initialize its data members.

An object’s constructor can pass arguments to


member-object constructors using member
initializers.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 22


Composition
When a class has member objects, they are created before the class
object that contains them (also known as the host object) is created.
The order of creation for the member objects is determined by the
order in which they are declared in the class definition.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 23


Composition Example: Date Class
class Address {
public:
Address(const std::string& s, const std::string& c, const std::string& st, const std::string&
z)
: street(s), city(c), state(st), zip(z)
{}
void print() const {
std::cout << street << ", " << city << ", " << state << ", " << zip << std::endl;
}
private:
std::string street;
std::string city;
std::string state;
std::string zip;
};

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 24


Composition Example: Employee Class
class Person {
public:
Person(const std::string& f, const std::string& l, const Address& a)
: firstName(f), lastName(l), address(a)
{}
void print() const {
std::cout << firstName << " " << lastName << ", Address: ";
address.print();
}
private:
std::string firstName;
std::string lastName;
Address address;
};

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 25


Composition Example: Employee Class Member Function
Definitions
int main() {
Address addr("123 Main St", "Anytown", "CA", "12345");
Person person("John", "Doe", addr);
person.print();
return 0;
}

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 26


Composition
A compilation error will occur if a member object in a class
does not have a default constructor and is not initialized with
a member initializer.

Suppose a member object is an object of another class. In that


case, it is generally not recommended to make it public as it
violates the encapsulation and hiding of the containing class's
implementation. Therefore, member objects of class types
should still be private, just like other data members, even
though they don't violate encapsulation when made public.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 27


friend functions and
friend classes
friend function
•A friend function is a function that is not a member of a class but can
access the non-public and public members of that class.

•Friend functions are defined outside the scope of the class they are
friends with.

•Standalone functions or entire classes can be declared friends of another


class.

•When a function or class has declared a friend, it is granted access to the


private and protected members of the class it is friends with.

•Friends of a class do not have access to the members of any objects of


that class; they only have access to the members of the class itself.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 29


friend function and friend class
•To allow a function to access a class’s private and protected
members, you can declare it as a friend of the class. To do
this, you must put the keyword "friend" before the function
prototype in the class definition.

•If you want to make all member functions of one class a


friend of another, you can use the "friend class" declaration.
To do this, you need to put a declaration of the form "friend
class ClassName;" in the definition of the other class. This will
allow all member functions of the first class to access the
private and protected members of the second class.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 30


friend function and friend class
class MyClass {
friend int someFunction(); // declare someFunction as a friend function of MyClass
};

class MyClassTwo;

class MyClassOne {
friend class MyClassTwo; // declare MyClassTwo as a friend class of MyClassOne
};

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 31


friend function and friend class
Friend functions are not member functions, and they can access
private, protected, and public members of a class

Access specifiers (private, protected, and public) are not


applicable to friend declarations

Friend declarations can be placed anywhere in the class


definition

It is recommended to place all friendship declarations at the


beginning of the class definition's body, without any access
specifier.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 32


friend function and friend class
Friendship is a granted relationship between two classes, where
one class explicitly declares the other class as its friend.

The friendship relation is not symmetric, which means that if


class A is a friend of class B, it cannot be inferred that class B is
also a friend of class A.

The friendship relation is not transitive, which means that if


class A is a friend of class B, and class B is a friend of class C, it
cannot be inferred that class A is a friend of class C.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 33


Modifying a Class's private Data With a Friend Function
#include <iostream>
class Vector {
public:
Vector(double x, double y) : x(x), y(y) {}
void print() const {
std::cout << "(" << x << ", " << y << ")" << std::endl;
}
// Friend function to compute the magnitude of a vector
friend double magnitude(const Vector& v);
private:
double x, y;
};

// Definition of friend function to compute magnitude


double magnitude(const Vector& v) {
return sqrt(v.x * v.x + v.y * v.y);
}
35

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 34


Modifying a Class's private Data With a Friend Function
int main() {
Vector v(3.0, 4.0);
v.print(); // prints "(3, 4)"
std::cout << "Magnitude of v: " << magnitude(v) << std::endl;
// prints "Magnitude of v: 5"
return 0;
}

36

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 35


Modifying a Class's private Data With a Friend Function
Output

(3, 4)
Magnitude of v: 5

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 36


Using the this Pointer
Using the this Pointer
Objects have data members and member functions.

Member functions can manipulate the data of the object they


belong to.

Member functions identify the object's data they need to


manipulate through a pointer called this.

this is a C++ keyword pointing to the object’s address currently


invoking the member function.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 38


Using the this Pointer
The this pointer of an object is not included in the object
itself.
This means that the memory occupied by this pointer is
not included in the object’s size, which is determined by
the sizeof operation.
The compiler instead passes this pointer as an implicit
argument to every non-static member function of the
object.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 39


Using the this Pointer
Objects reference their data members and member functions
using the this pointer.

The this pointer can be used implicitly or explicitly.

The type of the this pointer depends on the object's type and
whether the member function is declared const.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 40


Using the this Pointer
The type of the this pointer depends on the type of the object and the const
qualification of the member function.
In a non-const member function of a class Employee, the this pointer is of
type Employee* const. It is a constant pointer pointing to a non-const object
of the Employee class.
In a const member function of a class Employee, the this pointer is of type
const Employee* const. It is a constant pointer pointing to a constant object
of the Employee class.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 41


Using the this Pointer
#include <iostream>
class Counter {
public:
Counter(int initialValue = 0) : count(initialValue) {}
void increment() {
count++;
}
void printCount() {
std::cout << "Count: " << count << std::endl;
}
void printAddress() {
std::cout << "Object address: " << this << std::endl;
}
private:
int count;
};

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 42


Using the this Pointer
int main() {
Counter c1(10);
Counter c2(20);

c1.printCount(); // prints "Count: 10"


c2.printCount(); // prints "Count: 20"

c1.increment();
c1.printCount(); // prints "Count: 11"

c1.printAddress(); // prints the memory address of c1


c2.printAddress(); // prints the memory address of c2

return 0;
}

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 43


Using the this Pointer
OUTPUT

Count: 10
Count: 20
Count: 11
Object address: 0x7ffee5a5a998
Object address: 0x7ffee5a5a988

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 44


Dynamic Memory Management
with Operators
New and Delete
Dynamic Memory Management
In C++, developers can manage the allocation and deallocation
of memory for any built-in or user-defined type in a program.

This is called dynamic memory management, and it involves


using the new and delete operators to handle memory
allocation and deallocation.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 46


Dynamic Memory Management
We declare a pointer to an object of type Time using Time *timePtr

We allocate dynamic memory for an object of type Time using the new
operator as new Time

The new operator initializes the object using the default constructor of Time
and returns the memory address of the object as a Time * pointer

We assign the returned pointer to the previously declared pointer variable


timePtr

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 47


Dynamic Memory Management
We use the delete operator to free the memory allocated to a
dynamically allocated object.
delete timePtr;

The delete operator first calls the object’s destructor, to which


the pointer points, then deallocates the memory associated with
the object.

Once the memory is deallocated, it becomes available for reuse


by the system to allocate other objects.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 48


Dynamic Memory Management
Forgetting to release dynamically allocated memory can lead to
a situation where the program runs out of memory before it is
expected to.

This situation is called a "memory leak," which can cause


problems for the program and its system.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 49


Dynamic Memory Management
C++ allows initialization of newly created fundamental-type variables
using the new operator.

Initialization is performed by providing an initializer in parentheses


after the type, such as new double(3.14159).

The same syntax can be used to specify arguments to the


constructor of an object.

An example of this is new Time(12, 45, 0) which creates a new


Time object initialized to 12:45 PM.

int* ptr = new int(42);

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 50


Dynamic Object Arrays
Dynamic object arrays can be created using the new operator in
C++.

An example is a class called Employee.

The statement "myemployees = new Employee[12]" creates an


array of 12 Employee objects and assigns a pointer to the first
object to myemployees.

The delete[] operator is used to clear the memory allocated for


the array.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 51


Static Class Members
Static Class Members
There are cases where a single copy of a variable should be
shared by all objects of a class

In such cases, we use a static data member

Static data members are declared with the keyword "static"


and are initialized outside the class definition

Static data members can be accessed using the class name


and the scope-resolution operator (::)

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 53


Static Class Members
Such a variable represents "class-wide" information (i.e., a
property of the class shared by all instances, not a property of
a specific object of the class)

The declaration of a static member begins with keyword static

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 54


Static Class Members
Static data members can be used to store data that will be
shared among all objects of a class

Static data members are not global variables, as they have class
scope

Static members can be declared with any access specifier


(public, private, or protected)

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 55


Static Class Members
By default, a static data member of a fundamental type is
initialized to 0.

If you want to give it a different initial value, you can


initialize it once (and only once).

This initialization can be done in the definition of the static


data member.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 56


Static Class Members
Static members of a class are always available and exist even
when no objects of that class exist.

To access a public static class member when there are no class


objects, prefix the class name and the binary scope resolution
operator (::) to the name of the static member.

For example, suppose we have a public static variable called


"employeeCount" in a class called "Employee". In that case, it
can be accessed using the expression
"Employee::employeeCount" when no objects of the
"Employee" class exist.

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 57


Static Class Members
Public static class members can be accessed using the object's
name and the dot operator and by prefixing the class name and
the binary scope resolution operator to the member’s name.

To access private or protected static class members when no


class objects exist, provide a public static member function and
call it by prefixing its name with the class name and binary
scope resolution operator.

59

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 58


Static Member Functions
A static member function is not associated with any specific
class object but with the class as a whole.

A static member function can only access other static


members of the class and not the non-static members or
those of its base class.

For example, if class X has a static member function f(), it


cannot access the non-static members of X or the non-static
members of any base class of X.

60

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 59


Static Class Members: Example (car class)
class Car {
public:
Car(const std::string& make, const std::string& model); // constructor
~Car(); // destructor
const std::string& getMake() const; // return make
const std::string& getModel() const; // return model
static int getCount(); // return number of objects instantiated
private:
std::string make;
std::string model;
static int count; // number of objects instantiated
};

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 60


Static Class Members: Example:
Member Function Definitions
// define and initialize static data member at file scope
int Car::count = 0;

// define static member function that returns number of


// Car objects instantiated (declared static in Car.h)
int Car::getCount() {
return count;
}

// constructor initializes make and model


Car::Car(const std::string& make, const std::string& model)
: make(make), model(model) {
count++; // increment static count of cars
std::cout << "Car constructor for " << make << ' ' << model << " called." <<
std::endl;
}

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 61


Static Class Members: Example:
Member Function Definitions
// destructor deallocates memory for make and model strings
Car::~Car() {
std::cout << "~Car() called for " << make << ' ' << model << std::endl;
count--; // decrement static count of cars
}

const std::string& Car::getMake() const {


return make;
}

const std::string& Car::getModel() const {


return model;
}

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 62


Static Class Members: Example:
Member Function Definitions
int main() {
// use class name and binary scope resolution operator to
// access static number function getCount
std::cout << "Number of cars before instantiation of any objects
is "
<< Car::getCount() << std::endl;

// use new to dynamically create two new Cars


// operator new also calls the object's constructor
Car* car1Ptr = new Car("Toyota", "Corolla");
Car* car2Ptr = new Car("Honda", "Civic");
std::cout << "Number of cars after objects are instantiated is "
<< car1Ptr->getCount() << std::endl;
}

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 63


Static Class Members: Example:
Member Function Definitions
std::cout << "\n\nCar 1: " << car1Ptr->getMake() << " " << car1Ptr->getModel()
<< "\nCar 2: " << car2Ptr->getMake() << " " << car2Ptr->getModel() <<
"\n\n";

delete car1Ptr; // deallocate memory


car1Ptr = 0; // disconnect pointer from free-store space
delete car2Ptr; // deallocate memory
car2Ptr = 0; // disconnect pointer from free-store space

// no objects exist, so call static member function getCount again


// using the class name and the binary scope resolution operator
std::cout << "Number of cars after objects are deleted is "
<< Car::getCount() << std::endl;
return 0;
}

65

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 64


Static Class Members: Example:
Driver (Main) Program
Output

Number of cars before instantiation of any objects is 0


Car constructor for Toyota Corolla called.
Car constructor for Honda Civic called.
Number of cars after objects are instantiated is 2

Car 1: Toyota Corolla


Car 2: Honda Civic

~Car() called for Toyota Corolla


~Car() called for Honda Civic
Number of cars after objects are deleted is 0
66

CMP1002 - Lecture 6 ASSIST. PROF. ERKUT ARICAN 65


Thank you
End of Lecture 6.

You might also like