0% found this document useful (0 votes)
106 views

Module 15: Programming in C++: Partha Pratim Das

This document discusses constant objects in C++. It explains that constant objects cannot change their data members. Constant member functions can be invoked on constant objects as they do not change object data. Regular member functions cannot be used with constant objects as they may modify the object. The document provides examples demonstrating constant versus non-constant objects and member functions.

Uploaded by

swaraj bhatnagar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
106 views

Module 15: Programming in C++: Partha Pratim Das

This document discusses constant objects in C++. It explains that constant objects cannot change their data members. Constant member functions can be invoked on constant objects as they do not change object data. Regular member functions cannot be used with constant objects as they may modify the object. The document provides examples demonstrating constant versus non-constant objects and member functions.

Uploaded by

swaraj bhatnagar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 33

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

You might also like