W10-Class and Object in C++
W10-Class and Object in C++
3
The Need for New Types
• A C++ “Class" is simply a very-slightly modified Structure
• As with structures, we sometimes want new types:
• A calendar program might want to store information
about dates, but C++ does not have a Date type
• A student registration system needs to store info about
students, but C++ has no Student type
• A music synthesizer app might want to store information
about users' accounts, but C++ has no Instrument type
4
Introduction to Class
• A user-defined data type
• Represents the set of properties or methods that are
common to all objects of one type
• A blueprint for an object
Example: Car
• Cars have different names and brands, but all share some
common properties (4 wheels, Speed Limit, Mileage range,
etc)
5
Introduction to Object
• An instance of a class
• Represents the real-life entities
• Has an identity, state, and behavior. Each object contains data
and code to manipulate the data.
Example: “My Car”
• Characteristics like color, manufactured year, price, drive, and
break.
6
Introduction to Class
Elements of a Class
• member variables: State inside each object
• Also called "instance variables" or "fields"
• Declared as private
• Each object created has a copy of each field.
• member functions: Behavior that executes inside each
object
• Also called "methods"
• Each object created has a copy of each method
• The method can interact with the data inside that object
• Constructors and destructors are special type of member functions
7
Introduction to Class
The implementation of a Class
• When building a class, we provide an interface to the user of the class
that details how the class works. The user often does not have access
to the code itself, but the interface usually suffices to use the class
properly
• The interface is generally put into a header file, e.g., ClassName.h
• The header file shows the class functions and variables (even though
some may be private)
• The source code for the class member functions is held in a .cpp file,
e.g., ClassName.cpp
• The .cpp file is written by the implementer of the class, and they
implement all of the class functions
• The user generally does not have or need access to this code (though you
can get it for open source code libraries) 8
Class Implementation
• One toy example
Best Practice: Separate the class definition and member function
implementations into two files: classname.h and classname.cpp
// in MyClass.h // in MyClass.cpp
#ifndef MYCLASS_H #include "MyClass.h"
#define MYCLASS_H #include <iostream>
private:
int data;
};
#endif // MYCLASS_H
9
Class Implementation
• One toy example
// in MyClass.h
#ifndef MYCLASS_H
#define MYCLASS_H
class MyClass {
public:
MyClass(); Header Guards in C++:
MyClass(int a); • Preprocessor directives that help to avoid
~MyClass(){
std::cout<<“Bye!” <<data errors that arise when the same function
<<std::endl; or variable or class is included/defined
} more than once
void doSomething();
private: • Another choice:
int data; #pragma once
};
#endif // MYCLASS_H
10
Class Implementation
• One toy example
// in MyClass.h
#ifndef MYCLASS_H Member Access Specifier
#define MYCLASS_H
Default Constructor
Overloaded
class MyClass {
public: Parameterized Constructor Constructors
MyClass();
MyClass(int a);
~MyClass(){ Destructor
std::cout<<“Bye!” <<data
<<std::endl; Member Function
}
void doSomething();
Member Variable
private:
int data;
}; Make sure your class definition
ends with a semicolon.
#endif // MYCLASS_H
11
Member Access Specifiers
• Classes can limit the access to their member functions and data
• The three types of access a class can grant are:
o Public — Accessible wherever the program has access to an object of
the class
o private — Accessible only to member functions of the class, not
accessible outside the class
o Protected — Accessible to member functions of the class and its
derived classes (i.e., child classes), not accessible outside the class
12
Member Access Specifiers
• One toy example
// in MyClass.h
Member variables of a class are often
#ifndef MYCLASS_H defined as private. Why?
#define MYCLASS_H
- We want to encapsulate them. We can
class MyClass {
public:
provide controlled access to them by
MyClass(); defining other public/protected member
MyClass(int a); functions, e.g., user-defined functions like
~MyClass(){ getter() and setter().
std::cout<<“Bye!” <<data
<<std::endl;
}
void doSomething();
private:
int data;
};
#endif // MYCLASS_H
13
Constructor
• Special member function that initializes the data members of a class
object
• Its name is exactly the same as the class name
• A constructor CANNOT return a value and has NO return type (NOT
even void)
• There are 3 types of constructors:
- Default constructors
- Parametrized constructors
- Copy constructors
14
Default Constructor
• A constructor that can be invoked without any arguments, e.g. a
constructor with an empty parameter list, or a constructor with
default values for all of its arguments
• Never define more than one default constructor for a class.
• If you fail to write a constructor for a class, the compiler will
automatically define a default constructor that leaves all data
members un-initialized
15
Parametrized Constructor
• Pass arguments to constructors. The initial values are passed as
arguments to the constructor function
• The arguments passed to a constructor are typically used to initialise
the object’s member variables
16
Class Implementation
• One toy example Including the header file of the class
Detailed implementation of constructors
and other member functions.
// in MyClass.cpp
The scope resolution operator (i.e., #include "MyClass.h"
#include <iostream>
two colons ::) is used to indicate which
class the function belongs to. MyClass::MyClass(){ data = 0; }
MyClass::MyClass(int a){
data = a;
}
// in main.cpp void MyClass::doSomething() {
#include "MyClass.h" std::cout << ”Do something!”
#include <iostream> << std::endl;
using namespace std; }
int main() {
MyClass toyClass1;
toyClass1.doSomething();
cout<<
toyClass1.data<<endl;
MyClass toyClass2(10);
}
17
Class Implementation
• One toy example Including the header file of the class
Detailed implementation of constructors
and other member functions.
// in MyClass.cpp
The scope resolution operator (i.e., #include "MyClass.h"
#include <iostream>
two colons ::) is used to indicate which
class the function belongs to. MyClass::MyClass(){ data = 0; }
MyClass::MyClass(int a){
The default constructor will data = a;
be executed, i.e., data = 0. }
// in main.cpp void MyClass::doSomething() {
#include "MyClass.h" std::cout << ”Do something!”
#include <iostream> << std::endl;
using namespace std; }
int main() {
MyClass toyClass1;
toyClass1.doSomething();
cout<<
toyClass1.data<<endl;
MyClass toyClass2(10);
}
18
Class Implementation
• One toy example Including the header file of the class
Detailed implementation of constructors
and other member functions.
// in MyClass.cpp
The scope resolution operator (i.e., #include "MyClass.h"
#include <iostream>
two colons ::) is used to indicate which
class the function belongs to. MyClass::MyClass(){ data = 0; }
MyClass::MyClass(int a){
The default constructor will data = a;
be executed, i.e., data = 0. }
// in main.cpp void MyClass::doSomething() {
#include "MyClass.h" std::cout << ”Do something!”
#include <iostream> << std::endl;
using namespace std; }
int main() { Error!
MyClass toyClass1; “data” is private and cannot
toyClass1.doSomething(); be accessed outside the class.
cout<<
toyClass1.data<<endl; The parameterized constructor will be
MyClass toyClass2(10);
executed, i.e., data = 10.
}
19
Class Implementation
• When the class and member functions are small, we can define member
functions inside the class to improve readability --- but NOT recommended
for large/complex member functions and classes
#include <iostream>
class MyClass {
public:
MyClass() { data = 0; }
MyClass(int a) { data = a; }
~MyClass() {
std::cout << "Bye! " << data << std::endl;
}
void doSomething() {
std::cout << "Do something!" << std::endl;
}
private:
int data;
};
20
Class Implementation
• Constructors can initialize their members in two different ways.
• Initializer list way: a constructor can have an initializer list within the
definition but prior to the constructor body:
MyClass(int a): data(a) { }
https://www.ibm.com/docs/en/zos/2.4.0?topic=only-initialization-base-classes-members-c 21
Class Implementation
• Update the class definition with the constructors using an initializer list
#include <iostream>
class MyClass {
public:
MyClass(): data(0) {}
MyClass(int a): data(a) {}
~MyClass() {
std::cout << "Bye! " << data << std::endl;
}
void doSomething() {
std::cout << "Do something!" << std::endl;
}
private:
int data;
};
22
Copy Constructor
• A copy constructor is a special constructor in C++ that initializes a
new object as a copy of an existing object
• There are two types of copy constructor
- Default copy constructor
- User-defined copy constructor
23
Default Copy Constructor
#include <iostream>
class MyClass {
public:
MyClass();
MyClass(int a);
~MyClass(){
std::cout<<"Bye!"<<data <<std::endl;
}
void doSomething();
private:
int data; The compiler-generated default copy
};
constructor is called when initializing
MyClass::MyClass(){ data = 0; }
MyClass::MyClass(int a){
an object from another or assigning
data = a; one object to another.
}
int main() {
MyClass toyClass1(10);
MyClass toyClass2 = toyClass1;
MyClass toyClass3(toyClass1);
} 24
Default Copy Constructor
• What the default copy constructor actually does is as follows:
• You can still explicitly define the default copy constructor in C++, but
it is NOT necessary and NOT recommended.
25
User-defined Copy Constructor
#include <iostream>
class MyClass {
public: The user-defined copy
MyClass();
MyClass(int a); constructor MUST take a
// User-defined copy constructor const reference of the same
MyClass(const MyClass &obj) {
data = obj.data * 2; class as the parameter.
std::cout << "User-defined Copy constructor
is called!" << std::endl;
}
~MyClass(){
std::cout<<"Bye! "<<data <<std::endl; The user-defined copy
}
void doSomething(); constructor is called.
private:
int data;
}; toyClass2.data is 20 now!
MyClass::MyClass(){ data = 0; }
MyClass::MyClass(int a){
data = a;
}
void MyClass::doSomething() {
std::cout << "Do something!"
<< std::endl;
}
int main() {
MyClass toyClass1(10);
MyClass toyClass2 = toyClass1;
}
26
Shallow Copy vs. Deep Copy
• Shallow Copy:
- An object is created by simply copying the data of all variables of the
original object
- If a variable of the object are dynamically allocated memory (e.g.,
new), the copied object variable will also refer to the same memory
location -- only the memory address is copied!
• Deep Copy:
- It copies the data of all variables
- For variables using dynamically allocated memory, it also allocates
new memory resources to store the same value.
27
Shallow Copy vs. Deep Copy
• Default copy constructor can perform only shallow copy
#include <iostream>
class MyClass {
public:
int* data; // Pointer to dynamically allocated memory
// Constructor
MyClass(int val) {
data = new int(val); // Allocating memory
std::cout << "Constructor called, allocating memory at " << data <<
std::endl;
}
// Destructor
~MyClass() {
std::cout << "Destructor called, freeing memory at " << data <<
std::endl;
delete data; // Deallocating memory
}
};
int main() {
MyClass obj1(10); // Constructor called
MyClass obj2 = obj1; // Default copy constructor called – Shallow Copy!!!
Output
Constructor called, allocating memory at 0x1fff2b0
obj1.data: 20
obj2.data: 20
Destructor called, freeing memory at 0x1fff2b0
Destructor called, freeing memory at 0x1fff2b0
free(): double free detected in tcache 2
Aborted
29
Destructor
• A special member function that is automatically called whenever an
object of its class ceases to exist. Its main purpose is to release any
resources that the corresponding constructor allocated
• A destructor’s name is the same as the name of the class it belongs
to, except that the name is preceded by a tilde symbol (~)
• The destructor does not have arguments, and has no return type not
even void
• A destructor should be declared in the public section of the class
• There cannot be more than one destructor in a class.
• When a destructor is NOT specified in a class, compiler generates a
default destructor
• Generally, destructors are called in the reverse order of constructor
calls
30
Destructor
• Destructor is often used to free dynamically allocated memory,
avoiding memory leakage!
#include <iostream>
using namespace std;
class MyClass {
public:
int* data;
int size;
int main() {
MyClass obj1(10);
MyClass obj2(20);
MyClass obj3(30);
return 0;
} 31
Destructor
• Destructors are called in the reverse order of constructor calls
Output
Constructed! The array size is 10
Constructed! The array size is 20
Constructed! The array size is 30
Destroyed! The array size is 30
Destroyed! The array size is 20
Destroyed! The array size is 10
32
The this pointer in C++
• The this pointer in C++ is an implicit pointer that stores the
memory address of the calling object
• It is available in the member functions of a class and allows access
to its own members
- We will use arrow -> instead of dot . to access its members, as
this is a pointer
• It is often used to 1) avoid naming conflicts and 2) return *this
for method chaining
33
The this pointer in C++
#include <iostream>
using namespace std;
class MyClass {
private:
int number;
public:
// Constructor
MyClass(int number) {
this->number = number; // Using `this` to resolve naming conflict
}
MyClass& setValue(int x) {
this->number = x;
return *this;
} // this will allow method chaining like: obj.setValue(10).display();
public:
MyClass(int v) {value = v; } // Constructor
int main() {
MyClass obj1(10), obj2(20); Output
MyClass obj3 = obj1 + obj2; // Using overloaded + operator Value: 30
obj3.display();
MyClass obj4 = obj1.sum(obj2); // Using sum() function
Value: 30
obj4.display();
return 0;
}
36
Operator Overloading
#include <iostream>
using namespace std;
const after the member
function specifies that it is a
class MyClass {
private:
“read-only” function that will not
int value; alter the object of the class.
public:
MyClass(int v) {value = v; } // Constructor
int main() {
MyClass obj1(10), obj2(20); Output
MyClass obj3 = obj1 + obj2; // Using overloaded + operator Value: 30
obj3.display();
MyClass obj4 = obj1.sum(obj2); // Using sum() function
Value: 30
obj4.display();
return 0;
}
37
Overloading <<
• Can we define the operator<<() function as a member function here?
- Not appropriate!
38
Friend and Friend Functions
• In C++, private members of a class cannot be accessed directly outside the
class. A friend in C++ provides access to private and protected members
of another class. Friends come in three varieties:
- Friend functions
- Friend classes
- Friend member functions
• By making a function a friend to a class, you allow the function the same
access privileges that a member function of the class has.
39
Friend Functions
• Place a prototype in the class declaration and prefix the declaration with
the keyword friend:
friend ostream& operator<<(ostream& out, const MyClass& obj);
40
Operator Overloading with Friend
Function
#include <iostream>
using namespace std;
class MyClass {
private:
int value;
public:
MyClass(int v) {value = v; }
int main() {
MyClass obj1(10), obj2(20);
MyClass obj3 = obj1 + obj2; // Using overloaded + operator
cout << obj3 << endl;
return 0;
}
41
References:
42
Questions?
Thank You!