Module 15
Partha Pratim
Das
Module 15: Programming in C++
Objectives &
Outline
Const-ness
Constant
Objects
Constant Partha Pratim Das
Member
Functions
Constant Data
Department of Computer Science and Engineering
Members Indian Institute of Technology, Kharagpur
Credit Card
Example [email protected]
mutable
Members
Summary Tanwi Mallick
Srijoni Majumdar
Himadri B G S Bhuyan
NPTEL MOOCs Programming in C++ Partha Pratim Das 1
Module Objectives
Module 15
Partha Pratim Understand const-ness of objects in C++
Das
Understand the use of const-ness in class design
Objectives &
Outline
Constant
Objects
Constant
Member
Functions
Constant Data
Members
Credit Card
Example
mutable
Members
Summary
NPTEL MOOCs Programming in C++ Partha Pratim Das 2
Module Outline
Module 15
Partha Pratim Constant Objects
Das
Constant Member methods
Objectives &
Outline Constant Data members
Constant Credit Card Example
Objects
Constant
mutable Data members - logical and bitwise const-ness
Member Example
Functions
Constant Data
logical and bitwise const-ness
Members Usage of mutable
Credit Card
Example
mutable
Members
Summary
NPTEL MOOCs Programming in C++ Partha Pratim Das 3
Module 15: Lecture 29
Module 15
Partha Pratim Constant Objects
Das
Constant Member methods
Objectives &
Outline Constant Data members
Constant Credit Card Example
Objects
Constant
Member
Functions
Constant Data
Members
Credit Card
Example
mutable
Members
Summary
NPTEL MOOCs Programming in C++ Partha Pratim Das 4
Constant Objects
Like objects of built-in type, objects of user-defined types can also be made
Module 15
constant
Partha Pratim
Das
If an object is constant, none of its data members can be changed
The type of the this pointer of a constant object of class, say, MyClass is:
Objectives &
Outline
// Const Pointer to Const Object
Constant const MyClass * const this;
Objects
Constant
Member instead of
Functions
Constant Data // Const Pointer to non-Const Object
Members MyClass * const this;
Credit Card
Example
mutable as for a non-constant object of the same class
Members
A constant objects cannot invoke normal methods of the class lest these
Summary methods change the object
Let us take an example
NPTEL MOOCs Programming in C++ Partha Pratim Das 5
Program 15.01: Example: Non-Constant Objects
#include <iostream>
Module 15 using namespace std;
Partha Pratim class MyClass {
Das int myPriMember_;
public:
int myPubMember_;
Objectives &
MyClass(int mPri, int mPub) : myPriMember_(mPri), myPubMember_(mPub) {}
Outline
int getMember() { return myPriMember_; }
Constant void setMember(int i) { myPriMember_ = i; }
Objects void print() { cout << myPriMember_ << ", " << myPubMember_ << endl; }
};
Constant int main() {
Member MyClass myObj(0, 1); // Non-constant object
Functions
cout << myObj.getMember() << endl;
Constant Data myObj.setMember(2);
Members myObj.myPubMember_ = 3;
Credit Card myObj.print();
Example
return 0;
mutable
}
Members
---
Summary 0
2, 3
• It is okay to invoke methods for non-constant object myObj
• It is okay to make changes in non-constant object myObj by method (setMember())
• It is okay to make changes in non-constant object myObj directly (myPubMember )
NPTEL MOOCs Programming in C++ Partha Pratim Das 6
Program 15.02: Example: Constant Objects
#include <iostream>
Module 15 using namespace std;
Partha Pratim class MyClass {
Das int myPriMember_;
public:
int myPubMember_;
Objectives &
MyClass(int mPri, int mPub) : myPriMember_(mPri), myPubMember_(mPub) {}
Outline
int getMember() { return myPriMember_; }
Constant void setMember(int i) { myPriMember_ = i; }
Objects void print() { cout << myPriMember_ << ", " << myPubMember_ << endl; }
};
Constant int main() {
Member const MyClass myConstObj(5, 6); // Constant object
Functions
cout << myConstObj.getMember() << endl; // Error 1
Constant Data myConstObj.setMember(7); // Error 2
Members myConstObj.myPubMember_ = 8; // Error 3
Credit Card myConstObj.print(); // Error 4
Example
return 0;
mutable
}
Members
• It is not allowed to invoke methods or make changes in constant object myConstObj
Summary
• Error (1, 2 & 4) on method invocation typically is:
cannot convert ’this’ pointer from ’const MyClass’ to ’MyClass &’
• Error (3) on member update typically is:
’myConstObj’ : you cannot assign to a variable that is const
• With const, this pointer is const MyClass * const while the methods expects MyClass * const
• Consequently, we cannot print the data member of the class (even without changing it)
• Fortunately, constant objects can invoke (select) methods if they are constant member functions
NPTEL MOOCs Programming in C++ Partha Pratim Das 7
Constant Member Function
To declare a constant member function, we use the keyword const between
Module 15
the function header and the body. Like:
Partha Pratim
Das
void print() const { cout << myMember_ << endl; }
Objectives &
Outline A constant member function expects a this pointer as:
Constant const MyClass * const this;
Objects
and hence can be invoked by constant objects
Constant
Member In a constant member function no data member can be changed. Hence,
Functions
Constant Data
Members
void setMember(int i) const
Credit Card { myMember_ = i; } // data member cannot be changed
Example
mutable
Members
gives an error
Summary
Interesting, non-constant objects can invoke constant member functions (by
casting – we discuss later) and, of course, non-constant member functions
Constant objects, however, can only invoke constant member functions
All member functions that do not need to change an object must be
declared as constant member functions
NPTEL MOOCs Programming in C++ Partha Pratim Das 8
Program 15.03: Example:
Constant Member Functions
#include <iostream>
Module 15 using namespace std;
Partha Pratim class MyClass {
Das int myPriMember_;
public:
int myPubMember_;
Objectives &
MyClass(int mPri, int mPub) : myPriMember_(mPri), myPubMember_(mPub) {}
Outline
int getMember() const { return myPriMember_; }
Constant void setMember(int i) { myPriMember_ = i; }
Objects void print() const { cout << myPriMember_ << ", " << myPubMember_ << endl; }
};
Constant int main() {
Member MyClass myObj(0, 1); // Non-constant object
Functions const MyClass myConstObj(5, 6); // Constant object
Constant Data cout << myObj.getMember() << endl;
Members myObj.setMember(2);
Credit Card myObj.myPubMember_ = 3;
Example myObj.print();
mutable Output
cout << myConstObj.getMember() << endl;
Members 0
//myConstObj.setMember(7);
//myConstObj.myPubMember_ = 8; 2, 3
Summary
myConstObj.print(); 5
return 0; 5, 6
}
• Now myConstObj can invoke getMember() and print(), but cannot invoke setMember()
• Naturally myConstObj cannot update myPubMember
• myObj can invoke all of getMember(), print(), and setMember()
NPTEL MOOCs Programming in C++ Partha Pratim Das 9
Constant Data members
Often we need part of an object, that is, one or more data members to be
Module 15
constant (non-changeable after construction) while the rest of the data
Partha Pratim members should be changeable. For example:
Das
For an Employee: employee ID and DoB should be non-changeable
Objectives & while designation, address, salary etc. should be changeable
Outline For a Student: roll number and DoB should be non-changeable while
Constant year of study, address, gpa etc. should be changeable
Objects For a Credit Card: card number and name of holder should be
Constant non-changeable while date of issue, date of expiry, address, cvv
Member number gpa etc. should be changeable
Functions
Do this by making the non-changeable data members as constant
Constant Data
Members To make a data member constant, we need to put the const keyword
Credit Card before the declaration of the member in the class
Example
mutable A constant data member cannot be changed even in a non-constant
Members object
Summary A constant data member must be initialized on the initialization list
NPTEL MOOCs Programming in C++ Partha Pratim Das 10
Program 15.04: Example: Constant Data Member
#include <iostream>
Module 15 using namespace std;
class MyClass {
Partha Pratim const int cPriMem_;
Das int priMem_;
public:
const int cPubMem_;
Objectives &
int pubMem_;
Outline
MyClass(int cPri, int ncPri, int cPub, int ncPub) :
Constant cPriMem_(cPri), priMem_(ncPri), cPubMem_(cPub), pubMem_(ncPub) {}
Objects int getcPri() { return cPriMem_; }
void setcPri(int i) { cPriMem_ = i; } // Error 1: Assignment to constant data member
Constant int getPri() { return priMem_; }
Member void setPri(int i) { priMem_ = i; }
Functions };
int main() {
Constant Data MyClass myObj(1, 2, 3, 4);
Members
Credit Card cout << myObj.getcPri() << endl; myObj.setcPri(6);
Example cout << myObj.getPri() << endl; myObj.setPri(6);
mutable
cout << myObj.cPubMem_ << endl;
Members
myObj.cPubMem_ = 3; // Error 2: Assignment to constant data member
Summary
cout << myObj.pubMem_ << endl; myObj.pubMem_ = 3;
return 0;
}
• It is not allowed to make changes to constant data members in myObj
• Error 1:l-value specifies const object
• Error 2:’myObj’ : you cannot assign to a variable that is const
NPTEL MOOCs Programming in C++ Partha Pratim Das 11
Credit Card Example
Module 15
We now illustrate constant data members with a complete
Partha Pratim
Das example of CreditCard class with the following supporting
Objectives &
classes:
Outline
String class
Constant
Objects Date class
Constant
Member Name class
Functions
Constant Data
Address class
Members
Credit Card
Example
mutable
Members
Summary
NPTEL MOOCs Programming in C++ Partha Pratim Das 12
Program 15.05: String Class:
In header file with copy
#ifndef __STRING_H
Module 15 #define __STRING_H
#include <iostream>
Partha Pratim #include <cstring>
Das using namespace std;
class String { char *str_; size_t len_;
Objectives &
public:
Outline
String(const char *s) : str_(strdup(s)), len_(strlen(str_)) // ctor
Constant { cout << "String ctor: "; print(); cout << endl; }
Objects String(const String& s) : str_(strdup(s.str_)), len_(strlen(str_)) // cctor
{ cout << "String cctor: "; print(); cout << endl; }
Constant String& operator=(const String& s) {
Member if (this != &s) {
Functions free(str_);
str_ = strdup(s.str_);
Constant Data len_ = s.len_;
Members }
Credit Card return *this;
Example }
~String() { cout << "String dtor: "; print(); cout << endl; free(str_); } // dtor
mutable
void print() const { cout << str_; }
Members
};
Summary #endif // __STRING_H
• Copy Constructor and Copy Assignment Operator added
• print() made a constant member function
NPTEL MOOCs Programming in C++ Partha Pratim Das 13
Program 15.05: Date Class:
In header file with copy
#ifndef __DATE_H
Module 15 #define __DATE_H
#include <iostream>
Partha Pratim using namespace std;
Das
char monthNames[][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
Objectives &
char dayNames[][10] = { "Monday", "Tuesday", "Wednesday", "Thursday",
Outline
"Friday", "Saturday", "Sunday" };
Constant class Date {
Objects enum Month { Jan = 1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec };
enum Day { Mon, Tue, Wed, Thr, Fri, Sat, Sun };
Constant typedef unsigned int UINT;
Member UINT date_; Month month_; UINT year_;
Functions public:
Date(UINT d, UINT m, UINT y) : date_(d), month_((Month)m), year_(y)
Constant Data { cout << "Date ctor: "; print(); cout << endl; }
Members Date(const Date& d) : date_(d.date_), month_(d.month_), year_(d.year_)
Credit Card { cout << "Date cctor: "; print(); cout << endl; }
Example Date& operator=(const Date& d) { date_ = d.date_; month_ = d.month_; year_ = d.year_;
return *this;
mutable
}
Members
~Date() { cout << "Date dtor: "; print(); cout << endl; }
Summary void print() const { cout << date_ << "/" << monthNames[month_ - 1] << "/" << year_; }
bool validDate() const { /* Check validity */ return true; } // Not Implemented (NI)
Day day() const { /* Compute day from date using time.h */ return Mon; } // NI
};
#endif // __DATE_H
• Copy Constructor and Copy Assignment Operator added
• print(), validDate(), and day() made constant member functions
NPTEL MOOCs Programming in C++ Partha Pratim Das 14
Program 15.05: Name Class:
In header file with copy
#ifndef __NAME_H
Module 15 #define __NAME_H
#include <iostream>
Partha Pratim using namespace std;
Das
#include "String.h"
Objectives &
class Name {
Outline
String firstName_, lastName_;
Constant public:
Objects Name(const char* fn, const char* ln) : firstName_(fn), lastName_(ln)
{ cout << "Name ctor: "; print(); cout << endl; }
Constant Name(const Name& n) : firstName_(n.firstName_), lastName_(n.firstName_)
Member { cout << "Name cctor: "; print(); cout << endl; }
Functions Name& operator=(const Name& n) {
firstName_ = n.firstName_;
Constant Data lastName_ = n.lastName_;
Members return *this;
Credit Card }
Example ~Name() { cout << "Name dtor: "; print(); cout << endl; }
void print() const
mutable
{ firstName_.print(); cout << " "; lastName_.print(); }
Members
};
Summary #endif // __NAME_H
• Copy Constructor and Copy Assignment Operator added
• print() made a constant member function
NPTEL MOOCs Programming in C++ Partha Pratim Das 15
Program 15.05: Address Class:
In header file with copy
#ifndef __ADDRESS_H
Module 15 #define __ADDRESS_H
#include <iostream>
Partha Pratim using namespace std;
Das
#include "String.h"
Objectives &
class Address {
Outline
unsigned int houseNo_;
Constant String street_, city_, pin_;
Objects public:
Address(unsigned int hn, const char* sn, const char* cn, const char* pin) :
Constant houseNo_(hn), street_(sn), city_(cn), pin_(pin)
Member { cout << "Address ctor: "; print(); cout << endl; }
Functions Address(const Address& a) :
houseNo_(a.houseNo_), street_(a.street_), city_(a.city_), pin_(a.pin_)
Constant Data { cout << "Address cctor: "; print(); cout << endl; }
Members Address& operator=(const Address& a) {
Credit Card houseNo_ = a.houseNo_; street_ = a.street_; city_ = a.city_; pin_ = a.pin_;
Example return *this;
}
mutable
~Address() { cout << "Address dtor: "; print(); cout << endl; }
Members
void print() const {
Summary cout << houseNo_ << " "; street_.print(); cout << " ";
city_.print(); cout << " "; pin_.print();
}
};
#endif // __ADDRESS_H
• Copy Constructor and Copy Assignment Operator added
• print() made a constant member function
NPTEL MOOCs Programming in C++ Partha Pratim Das 16
Program 15.05: Credit Card Class:
In header file with edit options
#ifndef __CREDIT_CARD_H
Module 15 #define __CREDIT_CARD_H
#include <iostream>
Partha Pratim using namespace std;
Das #include "Date.h"
#include "Name.h"
#include "Address.h"
Objectives &
class CreditCard { typedef unsigned int UINT; char *cardNumber_;
Outline
Name holder_; Address addr_; Date issueDate_, expiryDate_; UINT cvv_;
Constant public:
Objects CreditCard(const char* cNumber, const char* fn, const char* ln,
unsigned int hn, const char* sn, const char* cn, const char* pin,
Constant UINT issueMonth, UINT issueYear, UINT expiryMonth, UINT expiryYear, UINT cvv) :
Member holder_(fn, ln), addr_(hn, sn, cn, pin), issueDate_(1, issueMonth, issueYear),
Functions expiryDate_(1, expiryMonth, expiryYear), cvv_(cvv)
{ cardNumber_ = new char[strlen(cNumber) + 1]; strcpy(cardNumber_, cNumber);
Constant Data cout << "CC ctor: "; print(); cout << endl; }
Members ~CreditCard() { cout << "CC dtor: "; print(); cout << endl; }
Credit Card
Example void setHolder(const Name& h) { holder_ = h; } // Change holder name
void setAddress(const Address& a) { addr_ = a; } // Change address
mutable
void setIssueDate(const Date& d) { issueDate_ = d; } // Change issue date
Members
void setExpiryDate(const Date& d) { expiryDate_ = d; } // Change expiry date
Summary void setCVV(UINT v) { cvv_ = v; } // Change cvv number
void print() const { cout<<cardNumber_<<" "; holder_.print(); cout<<" "; addr_.print();
cout<<" "; issueDate_.print(); cout<<" "; expiryDate_.print(); cout<<" "; cout<<cvv_;
};
#endif // __CREDIT_CARD_H
• Set methods added
• print() made a constant member function
NPTEL MOOCs Programming in C++ Partha Pratim Das 17
Program 15.05: Credit Card Class Application
#include <iostream>
Module 15 using namespace std;
Partha Pratim #include "CreditCard.h"
Das
int main() {
CreditCard cc("5321711934640027", "Sharlock", "Holmes",
Objectives &
221, "Baker Street", "London", "NW1 6XE", 7, 2014, 6, 2016, 811);
Outline
cout << endl; cc.print(); cout << endl << endl;;
Constant
Objects cc.setHolder(Name("David", "Cameron"));
cc.setAddress(Address(10, "Downing Street", "London", "SW1A 2AA"));
Constant cc.setIssueDate(Date(1, 7, 2017));
Member cc.setExpiryDate(Date(1, 6, 2019));
Functions cc.setCVV(127);
cout << endl; cc.print(); cout << endl << endl;;
Constant Data
Members return 0;
Credit Card }
Example // Construction of Data Members & Object
mutable
Members 5321711934640027 Sharlock Holmes 221 Baker Street London NW1 6XE 1/Jul/2014 1/Jun/2016 811
Summary // Construction & Destruction of temporary objects
5321711934640027 David Cameron 10 Downing Street London SW1A 2AA 1/Jul/2017 1/Jun/2019 127
// Destruction of Data Members & Object
• We could change address, issue date, expiry date, and cvv. This is fine
• We could change the name of the holder! This should not be allowed
NPTEL MOOCs Programming in C++ Partha Pratim Das 18
Program 15.06: Credit Card Class:
Constant data members
#ifndef __CREDIT_CARD_H
Module 15 #define __CREDIT_CARD_H
// Include <iostream>, "String.h", "Date.h", "Name.h", "Address.h"
Partha Pratim using namespace std;
Das
class CreditCard { typedef unsigned int UINT;
char *cardNumber_;
Objectives &
const Name holder_; // Holder name cannot be changed after construction
Outline
Address addr_;
Constant Date issueDate_, expiryDate_; UINT cvv_;
Objects public:
CreditCard(...) : ... { ... }
Constant ~CreditCard() { ... }
Member
Functions void setHolder(const Name& h) { holder_ = h; } // Change holder name
// error C2678: binary ’=’ : no operator found which takes a left-hand operand
Constant Data // of type ’const Name’ (or there is no acceptable conversion)
Members
Credit Card void setAddress(const Address& a) { addr_ = a; } // Change address
Example void setIssueDate(const Date& d) { issueDate_ = d; } // Change issue date
void setExpiryDate(const Date& d) { expiryDate_ = d; } // Change expiry date
mutable
void setCVV(UINT v) { cvv_ = v; } // Change cvv number
Members
Summary void print() { ... }
};
#endif // __CREDIT_CARD_H
• We prefix Name holder with const. Now the holder name cannot be changed after construction
• In setHolder(), we get a compilation error for holder = h; in an attempt to change holder
• With const prefix Name holder becomes constant – unchangeable
NPTEL MOOCs Programming in C++ Partha Pratim Das 19
Program 15.06: Credit Card Class:
Clean
#ifndef __CREDIT_CARD_H
Module 15 #define __CREDIT_CARD_H
// Include <iostream>, "String.h", "Date.h", "Name.h", "Address.h"
Partha Pratim using namespace std;
Das
class CreditCard { typedef unsigned int UINT;
char *cardNumber_;
Objectives &
const Name holder_; // Holder name cannot be changed after construction
Outline
Address addr_;
Constant Date issueDate_, expiryDate_; UINT cvv_;
Objects public:
CreditCard(...) : ... { ... }
Constant ~CreditCard() { ... }
Member
Functions void setAddress(const Address& a) { addr_ = a; } // Change address
void setIssueDate(const Date& d) { issueDate_ = d; } // Change issue date
Constant Data void setExpiryDate(const Date& d) { expiryDate_ = d; } // Change expiry date
Members void setCVV(UINT v) { cvv_ = v; } // Change cvv number
Credit Card
Example void print() { ... }
};
mutable
#endif // __CREDIT_CARD_H
Members
• Method setHolder() removed
Summary
NPTEL MOOCs Programming in C++ Partha Pratim Das 20
Program 15.06: Credit Card Class Application:
Revised
#include <iostream>
Module 15 using namespace std;
Partha Pratim #include "CreditCard.h"
Das
int main() {
CreditCard cc("5321711934640027", "Sharlock", "Holmes",
Objectives &
221, "Baker Street", "London", "NW1 6XE", 7, 2014, 6, 2016, 811);
Outline
cout << endl; cc.print(); cout << endl << endl;;
Constant
Objects // cc.setHolder(Name("David", "Cameron"));
cc.setAddress(Address(10, "Downing Street", "London", "SW1A 2AA"));
Constant cc.setIssueDate(Date(1, 7, 2017));
Member cc.setExpiryDate(Date(1, 6, 2019));
Functions cc.setCVV(127);
cout << endl; cc.print(); cout << endl << endl;;
Constant Data
Members return 0;
Credit Card }
Example // Construction of Data Members & Object
mutable
Members 5321711934640027 Sharlock Holmes 221 Baker Street London NW1 6XE 1/Jul/2014 1/Jun/2016 811
Summary // Construction & Destruction of temporary objects
5321711934640027 Sharlock Holmes 10 Downing Street London SW1A 2AA 1/Jul/2017 1/Jun/2019 127
// Destruction of Data Members & Object
• Now holder cannot be changed. So we are safe
• However, it is still possible to replace or edit the card number. This, too, should be disallowed
NPTEL MOOCs Programming in C++ Partha Pratim Das 21
Program 15.07: Credit Card Class:
cardMember Issue
#ifndef __CREDIT_CARD_H
Module 15 #define __CREDIT_CARD_H
// Include <iostream>, "String.h", "Date.h", "Name.h", "Address.h"
Partha Pratim using namespace std;
Das
class CreditCard { typedef unsigned int UINT;
char *cardNumber_; // Card number is editable as well as replaceable
Objectives &
const Name holder_; // Holder name cannot be changed after construction
Outline
Address addr_;
Constant Date issueDate_, expiryDate_; UINT cvv_;
Objects public:
CreditCard(...) : ... { ... }
Constant ~CreditCard() { ... }
Member
Functions void setAddress(const Address& a) { addr_ = a; } // Change address
void setIssueDate(const Date& d) { issueDate_ = d; } // Change issue date
Constant Data void setExpiryDate(const Date& d) { expiryDate_ = d; } // Change expiry date
Members void setCVV(UINT v) { cvv_ = v; } // Change cvv number
Credit Card
Example void print() { ... }
};
mutable
#endif // __CREDIT_CARD_H
Members
• It is still possible to replace or edit the card number
Summary
• To make the cardNumber non-replaceable, we need to make this pointer constant
• Further, to make it non-editable we need to make cardNumber point to a constant string
• Hence, we change char *cardNumber to const char * const cardNumber
NPTEL MOOCs Programming in C++ Partha Pratim Das 22
Program 15.07: Credit Card Class:
cardMember Issue
#ifndef __CREDIT_CARD_H
Module 15 #define __CREDIT_CARD_H
// Include <iostream>, "String.h", "Date.h", "Name.h", "Address.h"
Partha Pratim using namespace std;
Das class CreditCard {
typedef unsigned int UINT;
const char * const cardNumber_; // Card number cannot be changed after construction
Objectives &
const Name holder_; // Holder name cannot be changed after construction
Outline
Address addr_; Date issueDate_, expiryDate_; UINT cvv_;
Constant public:
Objects CreditCard(const char* cNumber, const char* fn, const char* ln,
unsigned int hn, const char* sn, const char* cn, const char* pin,
Constant UINT issueMonth, UINT issueYear, UINT expiryMonth, UINT expiryYear, UINT cvv) :
Member holder_(fn, ln), addr_(hn, sn, cn, pin), issueDate_(1, issueMonth, issueYear),
Functions expiryDate_(1, expiryMonth, expiryYear), cvv_(cvv)
{
Constant Data cardNumber_ = new char[strlen(cNumber) + 1]; // ERROR: No assignment to const pointer
Members strcpy(cardNumber_, cNumber); // ERROR: No copy to const C-string
Credit Card cout << "CC ctor: "; print(); cout << endl;
Example }
~CreditCard() { cout << "CC dtor: "; print(); cout << endl; }
mutable
Members
// Set methods and print method skipped ...
Summary };
#endif // __CREDIT_CARD_H
• cardNumber is now a constant pointer to a constant string
• With this the allocation for the C-string fails in the body as constant pointer cannot be assigned
• Further, copy of C-string (strcpy() fails as copy of constant C-string is not allowed
• We need to move these codes to the initialization list
NPTEL MOOCs Programming in C++ Partha Pratim Das 23
Program 15.07: Credit Card Class:
cardMember Issue Resolved
#include <iostream>
Module 15 using namespace std;
#include "String.h"
Partha Pratim #include "Date.h"
Das #include "Name.h"
#include "Address.h"
class CreditCard {
Objectives &
typedef unsigned int UINT;
Outline
const char * const cardNumber_; // Card number cannot be changed after construction
Constant const Name holder_; // Holder name cannot be changed after construction
Objects Address addr_; Date issueDate_, expiryDate_; UINT cvv_;
public:
Constant CreditCard(const char* cNumber, const char* fn, const char* ln,
Member unsigned int hn, const char* sn, const char* cn, const char* pin,
Functions UINT issueMonth, UINT issueYear, UINT expiryMonth, UINT expiryYear, UINT cvv) :
cardNumber_(strcpy(new char[strlen(cNumber)+1], cNumber)),
Constant Data holder_(fn, ln), addr_(hn, sn, cn, pin), issueDate_(1, issueMonth, issueYear),
Members expiryDate_(1, expiryMonth, expiryYear), cvv_(cvv)
Credit Card { cout << "CC ctor: "; print(); cout << endl; }
Example ~CreditCard() { cout << "CC dtor: "; print(); cout << endl; }
void setAddress(const Address& a) { addr_ = a; } // Change address
mutable
void setIssueDate(const Date& d) { issueDate_ = d; } // Change issue date
Members
void setExpiryDate(const Date& d) { expiryDate_ = d; } // Change expiry date
Summary void setCVV(UINT v) { cvv_ = v; } // Change cvv number
void print() { cout<<cardNumber_<<" "; holder_.print(); cout<<" "; addr_.print();
cout<<" "; issueDate_.print(); cout<<" "; expiryDate_.print(); cout<<" "; cout<<cvv_;
};
• Note the initialization of cardNumber in initialization list
• All constant data members must be initialized in initialization list
NPTEL MOOCs Programming in C++ Partha Pratim Das 24
Module 15: End of Lecture 29
Module 15
Partha Pratim Constant Objects
Das
Constant Member methods
Objectives &
Outline Constant Data members
Constant Credit Card Example
Objects
Constant
Member
Functions
Constant Data
Members
Credit Card
Example
mutable
Members
Summary
NPTEL MOOCs Programming in C++ Partha Pratim Das 25
Module 15: Lecture 30
Module 15
Partha Pratim mutable Data members
Das
Example
Objectives & logical and bitwise const-ness
Outline
Usage of mutable
Constant
Objects
Constant
Member
Functions
Constant Data
Members
Credit Card
Example
mutable
Members
Summary
NPTEL MOOCs Programming in C++ Partha Pratim Das 26
mutable Data Members
Module 15
While a constant data member is not changeable even in a non-constant
Partha Pratim object, a mutable data member is changeable in a constant object
Das
mutable is provided to model Logical (Semantic) const-ness against the
Objectives &
default Bit-wise (Syntactic) const-ness of C++
Outline
Note that:
Constant
Objects
mutable is applicable only to data members and not to variables
Reference data members cannot be declared mutable
Constant Static data members cannot be declared mutable
Member
Functions const data members cannot be declared mutable
Constant Data If a data member is declared mutable, then it is legal to assign a value to it
Members from a const member function
Credit Card
Example Let us see an example
mutable
Members
Summary
NPTEL MOOCs Programming in C++ Partha Pratim Das 27
Program 15.08: mutable Data Members
Module 15 #include <iostream>
using namespace std;
class MyClass {
Partha Pratim
int mem_;
Das
mutable int mutableMem_;
public:
Objectives & MyClass(int m, int mm) : mem_(m), mutableMem_(mm) {}
Outline int getMem() const { return mem_; }
void setMem(int i) { mem_ = i; }
Constant int getMutableMem() const { return mutableMem_; }
Objects void setMutableMem(int i) const { mutableMem_ = i; } // Okay to change mutable
};
Constant int main() {
Member const MyClass myConstObj(1, 2);
Functions
cout << myConstObj.getMem() << endl;
Constant Data
//myConstObj.setMem(3); // Error to invoke
Members
Credit Card cout << myConstObj.getMutableMem() << endl;
Example
myConstObj.setMutableMem(4);
mutable
Members return 0;
}
Summary
• setMutableMem() is a constant member function so that constant myConstObj can invoke it
• setMutableMem() can still set mutableMem because mutableMem is mutable
• In contrast, myConstObj cannot invoke setMem() and hence mem cannot be changed
NPTEL MOOCs Programming in C++ Partha Pratim Das 28
Logical vis-a-vis Bit-wise Const-ness
Module 15 const in C++, models bit-wise constant. Once an object
Partha Pratim is declared const, no part (actually, no bit) of it can be
Das
changed after construction (and initialization)
Objectives &
Outline However, while programming we often need an object to
Constant be logically constant. That is, the concept represented by
Objects
the object should be constant; but if its representation
Constant
Member need more data members for computation and modeling,
Functions
these have no reason to be constant.
Constant Data
Members mutable allows such surrogate data members to be
Credit Card
Example
changeable in a (bit-wise) constant object to model
mutable
Members logically const objects
Summary To use mutable we shall look for:
A logically constant concept
A need for data members outside the representation of the
concept; but are needed for computation
NPTEL MOOCs Programming in C++ Partha Pratim Das 29
Program 15.09:
When to use mutable Data Members?
• Typically, when a class represents a constant concept, and
Module 15 • It computes a value first time and caches the result for future use
Partha Pratim // Source: http://www.highprogrammer.com/alan/rants/mutable.html
Das
#include <iostream>
using namespace std;
Objectives &
class MathObject { // Constant concept of PI
Outline
mutable bool piCached_; // Needed for computation
Constant mutable double pi_; // Needed for computation
Objects public:
MathObject() : piCached_(false) { } // Not available at construction
Constant double pi() const { // Can access PI only through this method
Member if (!piCached_) { // An insanely slow way to calculate pi
Functions pi_ = 4;
for (long step = 3; step < 1000000000; step += 4) {
Constant Data pi_ += ((-4.0 / (double)step) + (4.0 / ((double)step + 2)));
Members }
Credit Card piCached_ = true; // Now computed and cached
Example }
mutable return pi_;
Members }
};
Summary int main() {
const MathObject mo;
cout << mo.pi() << endl; // Access PI
return 0;
}
• Here a MathObject is logically constant; but we use mutable members for computation
NPTEL MOOCs Programming in C++ Partha Pratim Das 30
Program 15.10:
When not to use mutable Data Members?
• mutable should be rarely used – only when it is really needed. A bad example follows:
Module 15
Improper Design (mutable) Proper Design (const)
Partha Pratim
Das class Employee { class Employee {
string _name; const string _name;
string _id; const string _id;
Objectives &
mutable double _salary; double _salary;
Outline
public: public:
Constant Employee(string name = "No Name", Employee(string name = "No Name",
Objects string id = "000-00-0000", string id = "000-00-0000",
double salary = 0) double salary = 0)
Constant : _name(name), _id(id) : _name(name), _id(id)
Member { _salary = salary; } { _salary = salary; }
Functions string getName() const; string getName() const;
void setName(string name);
Constant Data string getid() const; string getid() const;
Members void setid(string id);
Credit Card double getSalary() const; double getSalary() const;
Example void setSalary(double salary); void setSalary(double salary);
mutable void promote(double salary) const void promote(double salary)
Members {_salary = salary;} {_salary = salary;}
}; };
Summary --- ---
const Employee john("JOHN","007",5000.0); Employee john("JOHN","007",5000.0);
// ... // ...
john.promote(20000.0); john.promote(20000.0);
• Employee is not logically constant. If it is, then salary should also be const
• Design on right makes that explicit
NPTEL MOOCs Programming in C++ Partha Pratim Das 31
Module Summary
Module 15 Studied const-ness in C++
Partha Pratim In C++, there are three forms of const-ness
Das
Constant Objects:
Objectives & No change is allowed after construction
Outline
Cannot invoke normal member functions
Constant
Objects Constant Member Functions:
Constant Can be invoked by constant (as well as non-constant)
Member
Functions
objects
Cannot make changes to the object
Constant Data
Members Constant Data Members:
Credit Card
Example No change is allowed after construction
mutable Must be initialized in the initialization list
Members
Summary Further, learnt how to model logical const-ness over
bit-wise const-ness by proper use of mutable members
NPTEL MOOCs Programming in C++ Partha Pratim Das 32
Instructor and TAs
Module 15
Partha Pratim
Das Name Mail Mobile
Objectives &
Partha Pratim Das, Instructor [email protected] 9830030880
Outline Tanwi Mallick, TA [email protected] 9674277774
Constant
Srijoni Majumdar, TA [email protected] 9674474267
Objects Himadri B G S Bhuyan, TA [email protected] 9438911655
Constant
Member
Functions
Constant Data
Members
Credit Card
Example
mutable
Members
Summary
NPTEL MOOCs Programming in C++ Partha Pratim Das 33