Download as ppsx, pdf, or txt
Download as ppsx, pdf, or txt
You are on page 1of 87

PROPERTY & METHOD

OBJECT ORIENTED PROGRAMMING


Advisor: Trương Toàn Thịnh

1
CONTENTS
Introduction
Constructor
Destructor
Assignment operator (‘=’)
Parameters problems
Type–casting
Other problems

2
INTRODUCTION
Class of C++ includes: property &
method
Property and method have the scopes
◦ public: the scope of access is outside and
inside the class
◦ private: the scope of access is inside the class
class phanso{ void main(){
private: phanso p; Valid because the scope of ‘nhap’ is public
int tu; p.nhap(2, 3);
int mau; p.tu = 4;
public: }
void nhap(int, int);
void xuat(); Invalid because the scope of ‘tu’ is private
};

3
CONSTRUCTOR
Initializing the object’s data can use
◦ Function (example: the function ‘nhap(int,
int)’): If developer forgets calling this function,
the object will contain ‘rubbish’ data
◦ Constructor method
The constructor’s feature:
◦ Its name is the same as class name & has no
return-type
◦ Automatically run when initializing the object
to prepare the data for the object.
◦ Has many overloading constructor methods
4
CONSTRUCTOR
Types of constructors
class PhanSo{
private: Default constructor
int tu, mau;
public: Constructor with enough parameters
PhanSo();
PhanSo(int, int); Constructor from another object
PhanSo(const PhanSo&)
};
PhanSo::PhanSo(){
tu = 0; mau = 1; void main(){
} PhanSo p(2, 3);
PhanSo::PhanSo(int t, int m){ PhanSo q(p);
tu = t; mau = m; PhanSo t();
} cout << p.tu << “/” << p.mau << endl;
PhanSo::PhanSo(const PhanSo& p){ cout << q.tu << “/” << q.mau << endl;
tu = p.tu; mau = p.mau; cout << t.tu << “/” << t.mau << endl;
} }

5
CONSTRUCTOR
 Some notes:
◦ If we do not declare/define any constructor, the compiler
provides default constructor
class PhanSo{
int tu, mau;
public:
void xuat();
void nhap(int, int);
//…
};
void main(){ PhanSo t(); }

◦ If the data fields have no pointer, we can delete the constructor


copying from another object.
class PhanSo{
int tu, mau;
public: PhanSo(int, int);
};
PhanSo::PhanSo(int t, int m){ tu = t; mau = m; }
void main(){
PhanSo p(2, 3);
PhanSo q(p);
PhanSo t;
} 6
CONSTRUCTOR
 Some notes:
◦ Don’t use auto-generated copy method or assignment operator in class
with pointer member
class PhanSo {
int tu, mau;
public:
PhanSo();
PhanSo(int);
PhanSo(int, int);
};
PhanSo::PhanSo() { tu = 0; mau = 1; } A
B PhanSo::PhanSo(int t) { tu = t; mau = 1; }
PhanSo::PhanSo(int t, int m) { tu = t; mau = m; } C
void main(){
PhanSo p(2, 3); 1
2 PhanSo q(5);
PhanSo c; 3
c = 7; 4
} compiler generates assignment operator 7
CONSTRUCTOR
Example: consider the class MyIntArray
class MyIntArray{ void main(){
private: MyIntArray a(3);
int *pArr; int size; MyIntArray b(a);
public: a.update(1, 10); //a[1] = 10
MyIntArray(int); cout << b.get(1) << endl;
MyIntArray(); }
void update(int k, int val){pArr[k] = val;}
int get(int k){return pArr[k]}
};
MyIntArray::MyIntArray(){ 0 0 0
size = 0; pArr = NULL;
<100>
}
a.pArr
MyIntArray::MyIntArray(int n){ 10
size = n; b.pArr
pArr = new int[size];
for(int i = 0; i < size; i++)
pArr[i] = 0;
}
8
CONSTRUCTOR
Example: we need to build the constructor
copying from another object in case the
data fields have the pointer
class MyIntArray{ void main(){
private: MyIntArray a(3);
int *pArr; int size; MyIntArray b(a);
public: a.update(1, 10); //a[1] = 10
//… cout << b.get(1) << endl;
MyIntArray(const MyIntArr&); }
};
MyIntArray::MyIntArray(const MyIntArr& src){ 0 0 0
size = src.size; a.pArr
<100>
pArr = new int[size];
for(int i = 0; i < size; i++)
pArr[i] = src.pArr[i];
b.pArr 0 0 0
}
<200>

9
COMPARISON WITH C# & JAVA
C# and Java support “constructor
chaining” allowing this constructor to call
that constructor in the same class
Line Code C#
1 // Declare class
2 class PhanSo {
3 private int tu;
4 private int mau;
5 public PhanSo(): this(0, 1) {} // call other constructor
6 public PhanSo(int t, int m) {
7 tu = t;
8 mau = m;
9 }
10 };
10
COMPARISON WITH C# & JAVA
In C# and Java, if sub-class’ s constructor
calls base-class’s constructor, the
implementation of virtual function called
in base-class’s constructor is the
implementation of the nearest sub-class
In C++, if sub-class’ s constructor calls
base-class’s constructor, the
implementation of virtual function called
in base-class’s constructor is the
implementation of the base-class
11
COMPARISON WITH C# & JAVA
C++:
#include <iostream>
using namespace std;
class lopA {
public:
lopA();
virtual void logging(); //virtual method
};
class lopB: public lopA {
public:
2 lopB() {}
void logging(); // no need to add virtual keyword
};
3 lopA::lopA() {logging();}
4 void lopA::logging() {cout << “Phuong thuc logging cua lop A” << endl;}
void lopB::logging() {cout << “Phuong thuc logging cua lop B” << endl;}
void main(){
1 lopB b;
}
12
COMPARISON WITH C# & JAVA
C#
class lopA {
3 public lopA() {logging();}
public virtual void logging() { Console.WriteLine(“Phuong thuc logging cua lop A\n”); }
};
class lopB: lopA {
2 public lopB() {}
4 public override void logging() { Console.WriteLine(“Phuong thuc logging cua lop B\n”); }
};
class Program {
1 static void Main(string[] args) { lopB b = new lopB(); }
}

Java
class lopA {
3 public lopA() {logging();}
public void logging() { System.out.println(“Phuong thuc logging cua lop A\n”); }
};
class lopB extends lopA {
2 public lopB() {}
4 public void logging() { System.out.println(“Phuong thuc logging cua lop B\n”); }
};
public class TestConstructor {
1 public static void main() { lopB b = new lopB(); }
}
13
COMPARISON WITH C# & JAVA
Some notes:
◦ In C# and Java, if the constructor is error, the
destructor automatically is called, but not in C++
◦ C# & Java don’t support default copy constructor
◦ C# supports static constructor, but not in Java &
C++
◦ C#’s static constructor: static className()
 This method has no access modifier and parameter
 This method is called before the first instance’s
initialization and the static members’ definition
 This method is automatically called

14
DESTRUCTOR
Automatically called when the object is
useless and destroyed
Revoke the resource allocated for the objects
in their life
Cleaning up helps to resist the memory leak:
◦ The program is terminated due to lacking the
memory
◦ The other softwares cannot run due to the fact
that our program uses all the memory
◦ After our program runs, the computer hangs up
15
DESTRUCTOR (THE FEATURES)
Its name is the same as the class name
with ‘~’
Has no parameter & returned value
Each class has ONLY ONE destructor
Automatically run when the object is out
of usage scope
Run only ONE time

16
DESTRUCTOR
Example: consider MyIntArray
class MyIntArray{ void main(){
private: MyIntArray a(10);
int *pArr; int size; MyIntArray* b = new MyIntArray(20);
public: //…
MyIntArray(int); delete b;
~MyIntArray(); }
//…
}; 1. The destructor of object ‘a’ will be
MyIntArray::~MyIntArray(){ automatically called
if(size > 0){ 2. The destructor of ‘b’ will be automatically
size = 0; delete []pArr; pArr = NULL; called when running the statement ‘delete b’
}
}
MyIntArray::MyIntArray(int n){
size = n;
pArr = new int[size];
for(int i = 0; i < size; i++)
pArr[i] = 0;
} 17
COMPARISON WITH C# & JAVA
C# and Java do not allow programmer to
implement destructor method
C# and Java have garbage collector
mechanism
Garbage collector mechanism
automatically deallocates unused memory
Some mistakes of C++’s programmer
◦ Forget to free the allocated memory
◦ Still use the deallocated memory
◦ Free the memory being used
18
ASSIGNMENT OPERATOR
Operator helps the statement be more
natural
◦ Example:
PhanSo a(1, 2), b(2, 3);
PhanSo kq = a + b;
Theoperator may be binary or unary
Some operators cannot be overloaded
◦ Operators ‘.’, ‘?:’, ‘sizeof’ (in C)
◦ Operators ‘::’, ‘.*’, ‘typeid’ (in C++)
19
ASSIGNMENT OPERATOR
Assignment operator is used to assign the
value of this object to that object
C++ provides the default assignment
operator, copying each field from this
object to that object
Class with pointer field needs to re-define
the assignment operator
Class without pointer field doesn’t need
to re-define the assignment operator
20
ASSIGNMENT OPERATOR
Example: operator ‘=’ in MyIntArray
class MyIntArray{ void main(){
private: MyIntArray a, b, c(3);
int *pArr; int size; a = b = c;
public: }
MyIntArray& operator=(const MyIntArray&);
//… a b c
};
MyIntArray& MyIntArray::operator=(const MyIntArray& src){
=
if(this != &src){
delete []pArr;
size = src.size; = b
pArr = new int[size];
for(int i = 0; i < size; i++)
a
pArr[i] = src.pArr[i];
}
return *this;
}
Inside the method, this is the pointer containing the address of the
21
object calling that method
ASSIGNMENT OPERATOR
In the class inheritance, firstly call the
operator ‘=’ of base class
class MyIntArray : public Base{
private:
int *pArr; int size;
public:
MyIntArray& operator=(const MyIntArray&);
//…
};
MyIntArray& MyIntArray::operator=(const MyIntArray& src){
if(this != &src){
Base::operator=(src);
delete []pArr;
size = src.size;
pArr = new int[size];
for(int i = 0; i < size; i++) pArr[i] = src.pArr[i];
}
return *this;
} 22
ASSIGNMENT OPERATOR
 Can define the operators ‘>>’ or ‘<<’ in the file ‘.h’/‘cpp’
combined with keyword ‘friend’ (means these operators is a
friend of class)
 Syntax of unary operators (prefix or suffix): Return-type
ClassName::operator@()
◦ @: notation standing for the operator, such as ++ or –
◦ This operator has no input-parameter
+ Using unary
- or binary
* operator
/ depending
% on the ^problems &
| ~ ! = < > +=
-= *= /= %= ^= &= |=
<< >> >>= <<= == != <=
>= && || ++ -- ->* ,
-> [] () new new[] delete delete[]
23
ASSIGNMENT OPERATOR
Example: consider PhanSo
class PhanSo{
int tu, mau;
public:
PhanSo();
PhanSo(int, int);
PhanSo& operator+=(const PhanSo&);
PhanSo operator+(const PhanSo&);
bool operator==(const PhanSo&);
PhanSo& operator++();//++ prefix
PhanSo operator++(int);//++ suffix
friend ostream& operator<<(ostream&, const
PhanSo&);
//… 24
ASSIGNMENT OPERATOR
Example: consider PhanSo
PhanSo& operator+=(const PhanSo& src){ PhanSo& operator++(){//++ prefix
tu = tu*src.mau + mau*src.tu; tu+=mau;
mau = mau*src.mau; return (*this);
return *this; }
} PhanSo operator++(int){//++ suffix
PhanSo operator+(const PhanSo& src){ PhanSo tmp = *this;
PhanSo tmp = (*this); ++(*this);
tmp+=src; return tmp;
return tmp; }
}
bool operator==(const PhanSo& src){ void main(){
return ((tu == src.tu) && (mau == src.mau)); PhanSo a(1, 3), b(2, 5), c = a + b;
} cout << c << endl; // 11/15
cout << ++c << endl; // (11+15)/15
a += b;
cout << a << endl; // 11/15
cout << b++ << endl; // 2/5
cout << b << endl; // (2+5)/5
} 25
ASSIGNMENT OPERATOR
 Some conventions/advices:
◦ Only overload the operator when the program is more natural
◦ Assure the operator is reasonable, for example: cannot overload the
operator ‘+’ of fraction with the subtraction inside
◦ Only overload the operator when it is significant, for example:
cannot multiply two DAYS
◦ Assure the consistency for the pairs of operators, for example ==/!=,
>/<…
◦ Some objects with large size use “const” to improve efficiency
◦ Implement the operators using private members inside the class
◦ Some symmetric binary operators should use “friend” to implement
outside the class
◦ Some operators needing left value, such as operator=, operator[],
operator(), operator->, operator*= or operator++ must be
implemented inside the class as non-static method
◦ Use operator() to access the multi-dimensional array’s members 26
COMPARISON WITH C# & JAVA
 C++ supports operator overloading with normal, static or
virtual methods, but in C# operator overloading must be static
one
 C# does not allow to overload operator=
 A number of overloadable operators of C++ is larger than C#’s
 In C#, once overloading binary operator+, operator+= also is
auto-overloaded
class PhanSo {
int tu, mau;
public static PhanSo operator+(PhanSo x, PhanSo y){
PhanSo tmp = new PhanSo();
tmp.tu = tmp.tu*src.mau + tmp.mau*src.tu;
tmp.mau = tmp.mau*src.mau;
return tmp;
}
// other methods
}; 27
COMPARISON WITH C# & JAVA
Java does not supports operator
overloading, except String class
In Java, objects is processed with
reference type. For example, operator= or
operator== will assign and compare
between the reference variables, but not in
the memory they point to.
With the objects of discrete datatype, Java
supports available operators similar to
built-in datatype in C++
28
PARAMETER PROBLEMS
 Similarto structural variables, the object has the
same parameter-passing mechanism:
◦ Pass-by-value
◦ Pass-by-reference
◦ Pass-by-address (pass-by-pointer)
 Pass-by-value: the compiler creates the copy of the
object passed in
 Pass-by-reference: the compiler creates an ‘alias’ of
the object passed in
 Pass-by-address: depending on pass-by-value or
pass-by-reference, the compiler will process the
same as pass-by-value or pass-by-reference
29
Passing by value an instance of a class makes copy-constructor run
PARAMETER PROBLEMS
(Pass-by-value)
 Syntax:
◦ Return-type methodName(Datatype parameterName)
◦ Ex: int doSth(int a, int b, float c, Date d);
 Analysis:
◦ Variables a, b, c, d: formal arguments
◦ Outside variables used to call and pass into them are called actual
arguments
◦ When a caller calls the method, formal arguments are set up a separate
memory and passed
#include the value from
<iostream> actual
void arguments
main() { of caller
using namespace std; int n = 10;
<50> // Sum 1 + 2 + … + n cout << tinhTong(n) << endl;
n10 long tinhTong(int x) { }
long tong = 0;
while (x > 0) {
Notes of pass-by-value:
<70> tong = tong + x; --x; 1) Needs separate memory & copy
648290173
10 } operations
x5 return tong; 2) Can pass a constant or expression
} 30
Notes of
pass-by-
referenc PARAMETER PROBLEMS
e:
1) Need (Pass-by-reference)
not  Syntax:
separat
e ◦ Return-type methodName(Datatype& parameterName)
memory
& copy ◦ Ex: int doSth(int& a, int& b, float& c, Date& d);
operati  Analysis: when a caller calls the method, formal
ons
2) arguments uses the same memory as actual arguments
Cannot of caller
pass a
constan #include <iostream> <20> <30>
t or using namespace std; 5
10 5
10
void swapInt(int& a, int& b) { int temp = a; a = b; b = temp; } x y
expressi
on void main() {
int x = 5, y = 10; <???> <???>
cout << “Before swap: x = ” << x << “, y = ” << y << endl; <20> <30>
swapInt(x, y); a b
cout << “After swap: x = ” << x << “, y = ” << y << endl;
}
31
PARAMETER PROBLEMS
(Pass-by-address)
A pointer has a memory of it owns
containing the address of the memory it is
pointing to <50> <60> <???>
void controThamTri(int* p) { *p = 5; p = new int; } 539 <50>
<90> <60>
a pT q
void controThamChieu(int* &q) {
q = new int[3];
<80> <70>
q[0] = 10; q[1] = 7; q[2] = 4;
} <50>
<80>
p
void main() {
int a = 9, *pT = &a; <90> 10
*pT = 3;
cout << “(0) a = ” << a << endl; 7
cout << “(1) Con tro pT = ” << pT << “, gia tri *pT = ” << *pT << endl; 4
controThamTri(pT);
cout << “(2) Con tro pT = ” << pT << “, gia tri *pT = ” << *pT << endl;
controThamChieu(pT);
cout << “(3) Con tro pT = ” << pT << “, gia tri *pT = ” << *pT << endl;
cout << “, ” << pT[1] << “, ” << pT[2] << endl;
delete[] pT;
} 32
PARAMETER PROBLEMS
(Default parameter)
May set the default values for parameters
◦ Ex: int doSomething(float a, int b =5);
int doSomething(float a, int b = 5) { //… }
void main() {
int x = 9;
doSomething(x); // b = 5
}
Note: creating default parameter follows
from right to left
◦ Ex: int doSomething(int a = 3, int b); // wrong
33
PARAMETER PROBLEMS
(Variable arguments)
 May create a function without knowing a number of parameters
◦ Ex: float Avg(1, 2)  1.5
float avg(1, 2, 3)  2
 Syntax: datatype methodName(datatype v1, …)

void nhieuThamSo(int n, …) {
va_list dsThamSo; va_start(dsThamSo, n);
cout << “So luong tham so: ” << n << endl;
for(int i = 0; i < n; i++) {
int a = va_arg(dsThamSo, int);
cout << “Tham so ” << i + 1 << “ = ” << a << endl;
}
va_end(dsThamSo);
}
void main() {
int x = 3, k = 5, h = 7, z = 10;
nhieuThamSo(4, x, k, h, z); nhieuThamSo(2, x, z);
} 34
COMPARISON WITH C# & JAVA
C#: transmitting a class variable to a
function can use pointer–like or pass-by-
reference mechanism
<200>
class PhanSo { 31 2
public int ts, ms;
<100>
public PhanSo(int t, int m) {
ts = t; ms = m; q <200>
}
};
class MainProgram { <300>
static void Inc(PhanSo p) { p.ts += p.ms; }
static void Main(){ p <200>
PhanSo q = new PhanSo(1, 2);
Inc(q);
}
}; 35
COMPARISON WITH C# & JAVA
C#: transmitting a class variable to a
function can use pass-by-address-value
and pass-by-reference mechanisms
<200>
class PhanSo {
public int ts, ms;
1 2
public PhanSo(int t, int m) {
ts = t; ms = m;
} <100>
}; <400>
<200>
class MainProgram { q <600> 3 7
static void Change(PhanSo p) { p = new PhanSo(3, 7); }
static void Change(ref PhanSo p) { p = new PhanSo(3, 7); } <300>
static void Main(){ <600>
PhanSo q = new PhanSo(1, 2); <400>
<200>
p
Change(q); 3 7
Change(ref q); <500>
}
}; p <100> 36
COMPARISON WITH C# & JAVA
C#: also supports variable arguments
class MainProgram {
public static void PrintData(params object[] list) {
for(int i = 0; i < list.Length; i++)
Console.WriteLine((object)list[i]);
Console.WriteLine();
}
static void Main(){ PrintData(1, ‘a’, “Test”, 7.5,
‘Z’); }
};
C#: support “out” keyword for variable
only receiving the result
class MainProgram {
public static void Test(out int x) { x = 1; }
static void Main(){ int a; Test(out a); }
};
37
COMPARISON WITH C# & JAVA
Java:
◦ Uses pass-by-value with
primitive datatype including
String class
◦ Use pass-by-reference with
Array
◦ Use pass-by-address-value with
class object
38
PARAMETER PROBLEMS
Example: consider the case of PhanSo
class PhanSo{
int tu, mau;
public:
PhanSo(int, int);
void Update(int, int);
friend ostream& operator<<(ostream& os, const PhanSo&);
};
PhanSo::PhanSo(int t, int m) {
tu = t; mau = m;
}
void PhanSo::Update(int t, int m) {
tu = t; mau = m;
}
ostream& operator<<(ostream& os, const PhanSo& ps) {
os << ps.tu << "/" << ps.mau << endl;
return os;
}

39
PARAMETER PROBLEMS
Example: consider PhanSo
void ThayDoiThamTri(PhanSo q) {q.Update(10, 10);}
void ThayDoiThamChieu(PhanSo& q){q.Update(10, 10);}
void ThayDoiThamTriContro(PhanSo* q) {q->Update(10, 10);}
void ThayDoiThamChieuContro(PhanSo*& q) {q->Update(10, 10);}
void main() { <100>
PhanSo p(2, 3); p ={2, 3}
cout << p;
ThayDoiThamTri(p);
cout << p; q ={2, 3} Pass-by-value
ThayDoiThamChieu(p); <200>
cout << p; q ={2, 3} Pass-by-reference
//////////////////////////////////////
<100>
PhanSo* t = new PhanSo(2, 3);
<500> <500>
cout << *t;
ThayDoiThamTriContro(t); t {2, 3} q Pass-by-pointer-reference
cout << *t; <600>
ThayDoiThamChieuContro(t);
q Pass-by-pointer-value
cout << *t;
<700>
} 40
TYPE–CASTING
C++ supports two type-casting methods:
◦ Implicit casting
◦ Explicit casting
 Static
 Dynamic
 C-style
 Const
 Re-interpret
Developer can:
◦ Use the constructor to type-cast
◦ Use the operator to type-cast
41
TYPE–CASTING (IMPLICITLY)
https://www.geeksforgeeks.org/type-conversion-in-c/

 Done by the compiler without any external trigger


from the user
 Generally takes place when in an expression more than
one data type is present. In such condition type
conversion (type promotion) takes place to avoid lose
of data.
 All the data types of the variables are upgraded to the
data type of the variable with largest data type.
 It is possible for implicit conversions to lose
information, signs can be lost (when signed is
implicitly converted to unsigned), and overflow can
occur (when long long is implicitly converted to float).
42
TYPE–CASTING (IMPLICITLY)
https://www.geeksforgeeks.org/type-conversion-in-c/

Example:

#include <iostream>
using namespace std;
void main() {
int x = 10; // integer x
char y = ‘a’; // character c
// y implicitly converted to int. ASCII
// value of 'a' is 97
x = x + y;
// x is implicitly converted to float
float z = x + 1.0;
cout << “x = ” << x << endl
<< “y = ” << y << endl
<< “z = ” << z << endl;
}
43
TYPE–CASTING (EXPLICITLY)
https://www.geeksforgeeks.org/type-conversion-in-c/

User typecasts the result to make it of a


particular datatype. It can be done by 2
ways:
◦ Converting by assignment: done by explicitly
defining the required type in front of the
expression in parenthesis.
#include <iostream>
using namespace std;
void main() {
double x = 1.2;
// Explicit conversion from double to int
int sum = (int)x + 1;
cout << “Sum = ” << sum;
} 44
TYPE–CASTING (EXPLICITLY)
https://www.geeksforgeeks.org/type-conversion-in-c/

User typecasts the result to make it of a


particular datatype. It can be done by 2
ways:
◦ Conversion using Cast operator: A Cast
operator is an unary operator which forces one
datatype to be converted into another datatype.
◦ C++ supports four types of casting:
 Static Cast
 Dynamic Cast
 Const Cast
 Reinterpret Cast
45
https://www.geeksforgeeks.org/static_cast-in-c-type-casting-operators/

TYPE–CASTING (EXPLICITLY)
Static Cast: It is a compile time cast
◦ Simple example:
void main() {
float f = 3.5;
int b = static_cast<int>(f);
cout << b;
}

◦ Class example
int main()
class Int {
int x;
{ public:
1 Int obj(3); 2X
6 Int(int x_in = 0) : x{ x_in } {
3 string str = obj; cout << “Conversion Ctor called” << endl;
5 obj = 20; }
7 string str2 = static_cast<string>(obj); 48 operator string() {
9 obj = static_cast<Int>(30); cout << “Conversion Operator” << endl;
return 0; return to_string(x);
} }
}; 46
https://www.geeksforgeeks.org/static_cast-in-c-type-casting-operators/

TYPE–CASTING (EXPLICITLY)
Static Cast: It is a compile time cast
◦ Inheritance example:
#include <iostream> pr
using namespace std; ot
ec
te
class Base { }; d
an
class Derived : public Base { }; d
pr
iv
void main() { at
ea
Derived d1; re
n ot
Base* b2 = static_cast<Base*>(&d1); al
lo
} we
d

◦ void* example: use static_cast to cast ‘to and


from’ void pointer.
void main() {
int i = 10;
void* v = static_cast<void*>(&i);
int* ip = static_cast<int*>(v);
} 47
TYPE–CASTING (EXPLICITLY)
https://www.geeksforgeeks.org/dynamic-_cast-in-cpp/

Dynamic Cast:
◦ Mainly used for safe down-casting at run time
◦ Works only polymorphic base class

BASE CLASS

Downcasting Upcasting

DERIVED DERIVED
CLASS 1 CLASS 2

48
TYPE–CASTING (EXPLICITLY)
https://www.geeksforgeeks.org/dynamic-_cast-in-cpp/

Dynamic Cast:
◦ Example without polymorphic class
class Base {
void print() { cout << “Base” << endl; }
};
class Derived1 : public Base {
void print() { cout << “Derived1” << endl; }
};
class Derived2 : public Base {
void print() { cout << “Derived2” << endl; }
};
void main() {
Derived1 d1;
COMPILE ERROR
Base* bp = dynamic_cast<Base*>(&d1);
Derived2* dp2 = dynamic_cast<Derived2*>(bp);
“downcasting from
if (dp2 == nullptr) cout << “null” << endl; non-polymorphic
} base class”

49
TYPE–CASTING (EXPLICITLY)
https://www.geeksforgeeks.org/dynamic-_cast-in-cpp/

Dynamic Cast:
◦ Polymorphic class example: print “not null”
class Base {
virtual void print() { cout << “Base” << endl; }
};
class Derived1 : public Base {
void print() { cout << “Derived1” << endl; }
};
class Derived2 : public Base {
void print() { cout << “Derived2” << endl; }
};
void main() {
Derived1 d1;
Base* bp = dynamic_cast<Base*>(&d1); upcasting
Derived1* dp1 = dynamic_cast<Derived1*>(bp); downcasting
if (dp1 == nullptr) cout << “null” << endl;
else cout << “not null” << endl;
}

50
TYPE–CASTING (EXPLICITLY)
https://www.geeksforgeeks.org/dynamic-_cast-in-cpp/

Dynamic Cast:
◦ Polymorphic class example: print “null”
class Base {
virtual void print() { cout << “Base” << endl; }
};
class Derived1 : public Base {
void print() { cout << “Derived1” << endl; }
};
class Derived2 : public Base {
void print() { cout << “Derived2” << endl; }
};
void main() {
Derived1 d1;
Base* bp = dynamic_cast<Base*>(&d1); upcasting
Derived2* dp2 = dynamic_cast<Derived2*>(bp); error downcasting
if (dp2 == nullptr) cout << “null” << endl;
else cout << “not null” << endl;
}

51
TYPE–CASTING (EXPLICITLY)
https://www.geeksforgeeks.org/dynamic-_cast-in-cpp/

Dynamic Cast:
◦ Polymorphic class example: print “null”
class Base {
virtual void print() { cout << “Base” << endl; }
};
class Derived1 : public Base {
void print() { cout << “Derived1” << endl; }
};
class Derived2 : public Base {
void print() { cout << “Derived2” << endl; }
};
void main() {
Derived1 d1;
Base* bp = dynamic_cast<Base*>(&d1); upcasting
Derived1* dp1 = dynamic_cast<Derived1*>(bp); downcasting
if (dp1 == nullptr) cout << “null” << endl;
else cout << “not null” << endl;
try { Derived2& r1 = dynamic_cast<Derived2&>(d1); } error casting
catch (std::exception& e) { cout << e.what() << endl; }
}
52
https://www.geeksforgeeks.org/const_cast-in-c-type-casting-operators/

TYPE–CASTING (EXPLICITLY)
Const-cast: cast away the variables’s
constness
◦ Change non-const class members inside a const
member function
class student { void main() {
int roll; student s(3);
public: cout << “Old roll: ” << s.getRoll() << endl;
student(int r) : roll(r) {} s.fun();
void fun() const { cout << “New roll: ” << s.getRoll() << endl;
(const_cast <student*> (this) )->roll = 5; }
}
int getRoll() { return roll; } Compiler changes from “const student*
}; const this” to “student* const this”

53
https://www.geeksforgeeks.org/const_cast-in-c-type-casting-operators/

TYPE–CASTING (EXPLICITLY)
Const-cast: cast away the variables’
constness
◦ Pass const data to a function that doesn’t
receive const
int fun(int* ptr) { normal pointer
return (*ptr + 10);
}
int main()
{
const int val = 10;
const int *ptr = &val;
int *ptr1 = const_cast <int *>(ptr);
cout << fun(ptr1);
return 0;
}
54
https://www.geeksforgeeks.org/const_cast-in-c-type-casting-operators/

TYPE–CASTING (EXPLICITLY)
Const-cast: cast away the variables’
constness
◦ Being an undefined behavior to modify a value
initially declared as const
int fun(int* ptr) { normal pointer
*ptr = (*ptr + 10);
return (*ptr);
}
If erase this “const” int main() {
keyword, program const int val = 10;
will print 20
const int *ptr = &val;
int *ptr1 = const_cast <int *>(ptr);
cout << fun(ptr1);
cout << val; Maybe print 10

return 0;
} 55
https://www.geeksforgeeks.org/const_cast-in-c-type-casting-operators/

TYPE–CASTING (EXPLICITLY)
Const-cast: cast away the variables’
constness
◦ Being safe because casting won’t happen if the
type of cast is not same as original object
int main()
{
int a1 = 40;
const int* b1 = &a1;
char* c1 = const_cast <char *> (b1); // compiler error
*c1 = 'A';
return 0;
}
56
https://www.geeksforgeeks.org/const_cast-in-c-type-casting-operators/

TYPE–CASTING (EXPLICITLY)
Const-cast: cast away the variables’
constness
◦ Cast away volatile attribute

int main() {
int a1 = 40;
const volatile int* b1 = &a1;
cout << “typeid of b1 ” << typeid(b1).name() << ‘\n’;
int* c1 = const_cast <int *> (b1);
cout << “typeid of c1 ” << typeid(c1).name() << ‘\n’;
}

57
TYPE–CASTING (EXPLICITLY)
Re-interpret cast: cast the object of this
class into the object of that class (Two
classes can be completely different)
class A{};
class B{};

void main(){
A* a = new A();
B* b = reinterpret_cast<B*>(a);
}
58
https://www.geeksforgeeks.org/reinterpret_cast-in-c-type-casting-operators/

TYPE–CASTING (EXPLICITLY)
 Purpose of re-interpret cast:
◦ Typecast any pointer to any other data type
◦ Used when we want to work with bits
◦ Boolean value is converted into integer value
struct mystruct { int x, y; char c; bool b; };
void main() { <affd38> <affd3c> <affd40>

5
mystruct s; s.x = 5; s.y = 10; s.c = ‘a’; s.b = true;
int* p = reinterpret_cast<int*>(&s); s 10 a1
12 1 cout << sizeof(s) << endl;
2 cout << *p << endl;
x y c b
3 p++;
4 cout << *p << endl;
5 p++; p <affd3c>
<affd38>
<affd40>
6 char* ch = reinterpret_cast<char*>(p);
7 cout << *ch << endl; <affd40>
ch <affd41>
8 ch++;
9 bool* n = reinterpret_cast<bool*>(ch);
n <affd41>
X cout << *n << endl;

cout << *(reinterpret_cast<bool*>(ch));


} 59
https://www.geeksforgeeks.org/reinterpret_cast-in-c-type-casting-operators/

TYPE–CASTING (EXPLICITLY)
 Purpose of re-interpret cast:
◦ Typecast any pointer to any other data type
◦ Used when we want to work with bits
◦ Boolean value is converted into integer value
void main() {
1 int* p = new int(65); <100>
2 char* ch = reinterpret_cast<char*>(p); A
65
3 cout << *p << endl; <200>
4 cout << *ch << endl; <100>
p
5 cout << p << endl;
<300>
6 cout << &p << endl; <100>
7 cout << ch << endl; ch
8 cout << (void*)&ch << endl;
9 cout << (void*)ch << endl;
} 60
TYPE–CASTING (CONSTRUCTOR)
In some cases, we can utilize the
constructor to support the type-casting
Example: class PhanSo
class PhanSo{
int tu, mau;
public:
PhanSo(int);
};
3 PhanSo::PhanSo(int t){
tu = t; mau = 1;
}
void main(){
1 int t = 5;
2 PhanSo p = t;
} 61
TYPE–CASTING (OPERATOR)
Buildthe type-casting operator for class
PhanSo class PhanSo{
int tu, mau;
public:
PhanSo(int, int);
operator int();
};
462 PhanSo::operator int(){
return tu/mau;
}
void main(){
PhanSo p(6, 2);
1 int t1 = p; Implicitly
3 int t2 = int(p);
Explicitly
5 int t3 = (int)p;
} 62
OTHER PROBLEMS
Some problems of data members
◦ Static members
◦ The members being the type of
different class
◦ Constant method
Singleton pattern
Class with the static methods

63
STATIC MEMBER
 Circumstance: the need of using one data member
shared with all the objects
 C++ supports variable/static method (class-level
member)
◦ Don’t rely on any objects
◦ Members are shared with all the objects
 Syntax
◦ Declaration:
static <Data-type> Function-name(parameter-list);
static <Data-type> Variable-name;
◦ Definition:
<Data-type> ClassName::VariableName = …;

64
STATIC MEMBER
Example
class Test{
static int count;
public:
static int Show();
Test(){count++;}
~Test(){count--;};
};
int Test::Show(){
return count;
}
int Test::count = 0;
void main(){
Test a, b;
int cout<<Test::Show();
} 65
MEMBER OF CLASS TYPE
 Consider two classes: DUONGTRON & DIEM

class DUONGTRON{
DIEM I;
float R;
public:
DUONGTRON(){cout<<“Create the circle”;};
~DUONGTRON{cout<<“Destroy the circle”;};
};
class DIEM{
float X, Y;
public:
DIEM(){cout<<“Create point”;};
~DIEM(){cout<<“Destroy point”;};
};
66
MEMBER OF CLASS TYPE
Consider DUONGTRON & DIEM
void main(){
DUONGTRON dt;
}
“Create point”

“Create circle”

“Destroy circle”

“Destroy point”

67
USING INTIALIZER
Some cases of data member (property):
◦ A constant
◦ A reference
◦ An object of another class without default
constructor
 Using “initializer” to define the values
Syntax:

Class-name(parameter-list): 1st variable


name(1st value), 2nd variable name (2nd value)…
Note: initialization order is declaration order
in the class 68
USING INTIALIZER
Example:
<100> <200>
class A { void main(){ 10 20
float a; 1 A _a(1.0F); _a _b
public: A(float t) { a = t; } 2 B _b(2.0);
float get() { return a; } 3 Test test(3,_a,_b);
void set(float t) { a = t; } 4 test.Show();
}; 5 _a.set(10.0F);
class B { 6 _b.set(20.0);
double b; 7 test.Show();
public: B(double t) { b = t; } } 2
float get() { return b; }
_B
void set(double t) { b = t; } <100>
}; _A
class Test {
const int k; A& _A; B _B;
<300> test3
public:
Test(int t, A& ta, B tb) : k(t), _B(tb), _A(ta) {}
void Show() { cout << k << “ ” << _A.get() << “ ” << _B.get() << endl; }
};
69
CONST METHOD
 Being the method that is called and does not affect the values
of the object’s data members
 Rules:
◦ Non-constant/constant object can call constant method
◦ Constant object CANNOT call non-constant method
 Syntax: <Data-type> MethodName(Parameter-list) const;
class A{
public:
void test(){}
void testConst() const{}
};
void doSomething(A a, const A& b){
a.test();//OK
a.testConst();//OK
b.test();//NOT OK
b.testConst();//OK
} 70
SINGLETON PATTERN
When using the pattern singleton for a
class, we assure there is only one object
created
Features:
◦ The constructor must be private
◦ Have static method getting static object in the
class
A
-static A* _obj

-A() A getInstance(){
+static getInstance(): A return _obj;
}
71
SINGLETON PATTERN
Singleton source code
class A{ - Always define constructor
static A* obj; - Do not use default constructor
A();
- Put constructor into private or
public:
static A* getInstance(); protected scope
}; - Variable called “obj” is assigned
A* A::obj = NULL; NULL
A::A(){//…} - Return “obj” variable when
A* A::getInstance(){
developer calls “getInstance()” static
if(!obj) obj = new A();
return obj; method
}
void main(){
A* a = A::getInstance();
} 72
SINGLETON PATTERN
Example: applying singleton
class A{ class SortAlg{
static A* obj; static SortAlg* obj;
A(); SortAlg();
void (*currentAlg)(float[], int);
public: public:
static A* getInstance(); static SortAlg* getInstance(void (*pAlg)(float[], int) = NULL);
static void InterchangeSort(float[], int);
//…sort algorithms
void Sort(float[], int);
}; };
A* A::obj = NULL; SortAlg* SortAlg::obj = NULL;
A::A(){//…} SortAlg::SortAlg(){currentAlg = InterchangeSort;}
A* A::getInstance(){ SortAlg* SortAlg::getInstance(void (*pAlg)(float[], int) = NULL){
if(!obj) obj = new A(); if(!obj) obj = new SortAlg();
if(pAlg != NULL) obj->currentAlg = pAlg;
return obj; return obj;
} }
void SortAlg::InterchangeSort(float a[], int n){//…}
void SortAlg::Sort(float a[], int n){
if(currentAlg != NULL) currentAlg(a, n);
}
73
SINGLETON PATTERN
Example: applying singleton
void main(){ void main(){
//Prepare data float a[] = {1.4F, -5.2F, 3.3F, 0}; int n = sizeof(a)/sizeof(a[0]);
A* a = A::getInstance(); SortAlg* a = SortAlg::getInstance();
//Use a to solve the problem a->Sort(a, n);
} }

◦ “getInstance” does not pass the parameter and use


InterchangeSort passed in the constructor
◦ Use the operator ‘->’ when calling method of the
structural pointer
Syntax of array of function pointer:
void (*menu[])(float[], int) = {SortAlg::SelectionSort, …,
SortAlg::InterchangeSort} 74
SINGLETON PATTERN
Example: build a “pure static” class
class SortAlg{ void main(){
SortAlg(){}; float a[] = {1.4F, -5.2F, 3.3F};
int n = sizeof(a)/sizeof(a[0]);
void (*currentAlg)(float[], int);
public: SortAlg::setAlgorithm(SortAlg::SelectionSort);
static void InterchangeSort(float[], int); SortAlg::Sort(a, n);
static void InsertionSort(float[], int); }
static void SelectionSort(float[], int); - This is a pure static solution
static void SetAlgorithm(void(*pAlg)(float[], int)); - No creating object of this class
static void Sort(float[], int);
- To access the “class-level”
};
void (*SortAlg::currentAlg)(float[], int) = InsertionSort; methods, we use the syntax:
void SortAlg::setAlgorithm(void (*pAlg)(float[], int)){ ClassName::MethodName()
if(pAlg != NULL) currentAlg = pAlg; - This is a way of reconstructing
}
the “legacy” library, such as Math
void SortAlg::InterchangeSort(float a[], int n){//…}
void SortAlg::InsertionSort(float a[], int n){//…} or Graphic libraries
void SortAlg::SelectionSort(float a[], int n){//…}
void SortAlg::Sort(float a[], int n){
if(currentAlg != NULL) currentAlg(a, n); 75
UPDATES IN C++
 Use notation “{}” to initialize the variable
void main(){
vector<int> a = {1, 2, 3, 4}; // Initialize
cout << a.size() << endl;
a = {5, 6, 7, 8, 9}; // Assign
cout << a.size() << endl;
}

 Use “decltype” & “auto” in variable arguments


auto findMax(int n, auto f, …) void main(){
{ int m = findMax(3, 5, 1, 8);
auto val = f, largest = f; cout << m << endl;
va_list vl; va_start(vl, f); double n = findMax(4, 1.2, 2.2, 0.9, 7.2);
for(int i = 1; i < n; i++) { cout << n << endl;
val = va_arg(vl, decltype(f)); }
if(val > largest) largest =
Note: the types of all parameters must
val;
be the same
}
var_end(vl); 76
UPDATES IN C++
Example of PHANSO
class PhanSo { ostream& operator<<(ostream& out, const PhanSo& src){
int tu, mau; if(src.mau == 0) out << “{inf.}”;
public: else if (src.mau == 1 || src.tu == 0) out << src.tu;
PhanSo(int t = 0, int m = 1): tu(t):mau(m){} else out << src.tu << “/” << src.mau;
const PhanSo operator+(const PhanSo& ps) const { return out;
PhanSo tmp; }
tmp.tu = tu*ps.mau + ps.tu*mau; void main(){
tmp.mau = mau*ps.mau; PhanSo p = findMax(3, PhanSo(1,2), PhanSo(2,3), PhanSo(5,6));
return tmp; cout << p << endl;
} }
const bool operator<(const PhanSo& ps) const {
PhanSo temp(-ps.tu, ps.mau);
temp = (*this) + temp;
return (temp.tu * temp.mau < 0);
}
friend ostream& operator<<(ostream& out, const PhanSo&);
};

Some limitation:
- Must provide a number of elements
- Compiler cannot detect if all members in array are not the same type77
UPDATES IN C++(USING {})
Using class “Initializer_list<T>” in a
constructor
class MyIntArray {
vector<int> Data;
<vector> defined copy constructor
public:
int size() { return Data.size(); }
void resize(int m) { Data.resize(m); }
MyIntArray(const initializer_list<int>& L) :Data{ L } {}
int& operator[](int i) { return Data.at(i); }
friend ostream& operator<<(ostream& out, MyIntArray& a) {
for (auto& x : a.Data) { out << x << “ ”; }
return out;
}
};
void main(){
MyIntArray b{ 1,4,5,6 }; cout << “b: ” << b << endl;
b = { 7,8,9,3 }; cout << “b: ” << b << endl;
}
78
Note: may declare MyIntArray b = {1, 4, 5, 6}
UPDATES IN C++(USING {})
2D-Array example with
“Initializer_list<T>”
typedef vector<int> IntVector; friend ostream& operator<<(ostream& out, IntArray2D& a) {
typedef initializer_list<int> IntInitializerList; for (int i = 0; i < a.xSize(); i++) {
class IntArray2D { for (int j = 0; j < a[i].size(); j++) out << a[i][j] << “ ”;
vector<IntVector> Data; out << endl;
public: }
int xSize() const { return Data.size(); } return out;
int ySize() const { return Data[0].size(); } }
IntVector& operator[](int i) { return Data.at(i); } void main(){
void resize(int m, int n) { IntArray2D A{ {1,2,3},{4,5,6},{7,8,9} };
if (m < 0) m = -m; if (n < 0) n = -n; cout << “m = ” << A.xSize() << “, n = ” << A.ySize() << endl;
Data.resize(m); cout << A;
for (auto& a : Data) { a.resize(n); } IntArray2D B(2, 2), C{3, 4};
} }
IntArray2D(int m, int n) { resize(m, n); }
IntArray2D(const initializer_list<IntInitializerList> & L2D) {
for (auto& L : L2D) { Data.push_back(L); } <vector> defined copy constructor
}
friend ostream& operator<<(ostream& out, IntArray2D& a);
};
79
UPDATES IN C++
(Implicit initializer_list parameter)
Method with vector<T>, where T is
defined (such as int or float), no need to
use initializer_list<T>
int findMaxInt(const vector<int>& a){ void main(){
int lc = a.front(); int m = findMaxInt({ 1,4,5,6 });
for(auto& v: a) { }
if(lc < v) lc = v;
}
<vector> defined copy constructor
return lc;
}
Similar to template method
template <class T> void main(){
T findMaxInt(const vector<T>& a){ int m = findMaxInt<int>({ 1,4,5,6 });
auto lc = a.front(); }
for(auto& v: a) { if(lc < v) lc = v; }
return lc;
} 80
UPDATES IN C++
(Implicit initializer_list parameter)
The class “MyIntArray” DOES NOT
USE initializer_list<int>
class MyIntArray { void main(){
vector<int> Data; MyIntArray b{ 1,4,5,6 }; // error compile
public: MyIntArray b({ 1,4,5,6 }); // Correct
int size() { return Data.size(); } b = { 7,8,9,3 }; // error compile
void resize(int m) { Data.resize(m); } b = vector<int>{ 7,8,9,3 }; // Correct
MyIntArray(const vector<int>& L) :Data{ L } {} }
int& operator[](int i) { return Data.at(i); }
friend ostream& operator<<(ostream& out, MyIntArray& a) {
for (auto& x : a.Data) { out << x << “ ”; }
return out;
}
};

81
UPDATES IN C++
(Implicit initializer_list parameter)
The class “IntArray2D” DOES NOT USE
initializer_list<int>
typedef vector<int> IntVector; friend ostream& operator<<(ostream& out, IntArray2D& a) {
//typedef initializer_list<int> IntInitializerList; for (int i = 0; i < a.xSize(); i++) {
class IntArray2D { for (int j = 0; j < a[i].size(); j++) out << a[i][j] << “ ”;
vector<IntVector> Data; out << endl;
public: }
int xSize() const { return Data.size(); } return out;
int ySize() const { return Data[0].size(); } }
IntVector& operator[](int i) { return Data.at(i); } void main(){
void resize(int m, int n) { IntArray2D A({ {1,2,3},{4,5,6},{7,8,9} });
if (m < 0) m = -m; if (n < 0) n = -n; cout << A;
Data.resize(m); A = IntArray2D({{4, 1, 2, 3}, {7, 4, 5, 6}, {6, 7, 8, 9}});
for (auto& a : Data) { a.resize(n); } cout << A;
} }
IntArray2D(int m, int n) { resize(m, n); }
IntArray2D(const vector<IntVector> & L2D) {
for (auto& L : L2D) { Data.push_back(L); }
}
friend ostream& operator<<(ostream& out, IntArray2D& a);
};
82
UPDATES IN C++
(Keyword ‘delete’)
“delete” is used to deallocate the memory
It can be used to disable the operators in
the class
class SomeClass {
Operator disabled disable operator
// Some properties
public:
void operator delete(void*) = delete;
void operator delete[](void*) = delete;
friend void ObjFree(SomeClass* pObj) {
// deallocate the memory…
}
// Some methods
};
The statement “delete pObj” is invalid
83
UPDATES IN C++
(Keyword ‘delete’)
Example of IntArray2D
typedef vector<int> IntVector; friend ostream& operator<<(ostream& out, IntArray2D& a) {
typedef initializer_list<int> IntInitializerList; for (int i = 0; i < a.xSize(); i++) {
class IntArray2D { for (int j = 0; j < a[i].size(); j++) out << a[i][j] << “ ”;
vector<IntVector> Data; out << endl;
public: }
int xSize() const { return Data.size(); } return out;
int ySize() const { return Data[0].size(); } }
IntVector& operator[](int i) { return Data.at(i); } void main(){
void resize(int m, int n) { IntArray2D A{ {1,2,3},{4,5,6},{7,8,9} }; // Correct
if (m < 0) m = -m; if (n < 0) n = -n; IntArray B; // Correct
Data.resize(m); IntArray2D B(2, 2), C{3, 4}; // Incorrect
for (auto& a : Data) { a.resize(n); } }
}
IntArray2D(){}; //IntArray2D(int m, int n) { resize(m, n); }
IntArray2D(int m, …) = delete; All constructors at least one
IntArray2D(const initializer_list<IntInitializerList> & L2D) { parameter are not allowed
for (auto& L : L2D) { Data.push_back(L); }
}
friend ostream& operator<<(ostream& out, IntArray2D& a);
};
84
UPDATES IN C++
(Keyword ‘default’)
“default”asks the compiler to generate
some default methods
Example of default constructor
◦ If user defines any constructor in class, default
constructor won’t be auto-generated
◦ Can write this default constructor or use
“default” keyword
class IntArray2D {
// …
IntArray2D() = default; // or IntArray2D(){}
// …
}; 85
UPDATES IN C++
(Move constructor)
Example of copy constructor
void main() {
class Move {
vector<Move> vec;
int* data;
vec.push_back(10); vec.push_back(20);
public:
} 1) Create “Hidden” Move object 10
4 1 Move(int d) { 2) Create the 1 Move object of vector
st

data = new int; *data = d; 3) Destroy “Hidden” Move object 10


4) Create “Hidden” Move object 20
}; 5) Create the 2 Move object of vector
nd

6 5 2 Move(const Move& source){ 6) Create the new 1 Move object of vector


st

7) Destroy the old 1 Move object of vector


st
data = new int; *data = (*source.data); 8) Destroy “Hidden” Move object 20
} 9) Destroy the new 1 Move object of vector
st

X) Destroy the 2 Move object of vector


nd
X 9 8 7 3 ~Move() {
if (data != nullptr) { cout << “Destructor is called for ” << *data << endl; }
else cout << “Destructor is called” << “ for nullptr” << endl;
delete data;
}
};
86
UPDATES IN C++
(Move constructor)
Example of move constructor
class Move { void main() {
int* data; vector<Move> vec;
public: vec.push_back(10); vec.push_back(20);
4 1 Move(int d) { data = new int; *data = d; };}
6 Move(const Move& source){ 1) Create “Hidden” Move object 10
2) Create the 1 Move object of vector (Move constructor)
st

data = new int; *data = (*source.data); 3) Destroy “Hidden” Move object 10 (nullptr)
} 4) Create “Hidden” Move object 20
5) Create the 2 Move object of vector (Move constructor)
nd

5 2 Move(Move&& source){ 6) Create the new 1 Move object of vector


st

data = source.data; source.data = nullptr; 7) Destroy the old 1 Move object of vector
st

8) Destroy “Hidden” Move object 20 (nullptr)


} 9) Destroy the new 1 Move object of vector
st

X 9 8 7 3 ~Move() { X) Destroy the 2 Move object of vector


nd

if (data != nullptr) { cout << “Destructor is called for ” << *data << endl; }
else cout << “Destructor is called” << “ for nullptr” << endl;
delete data;
}
};
&& is a new reference operator defined in the C++11 standard. int&& a means “a” is an r-value reference87

You might also like