Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
cout
cout
cout
cout
<<
<<
<<
<<
}
};
int main()
{
const Customer c1("Pravasi Meet", "Ice Cream", 3, 100);
c1.display();
c1.changePlacedOrder("GulabJammuns");
c1.changeBill(150);
c1.display();
return 0;
}
Output:
Customer name is: Pravasi Meet
Food ordered by customer is: Ice Cream
table no is: 3
Total payable amount: 100
Customer name is: Pravasi Meet
Food ordered by customer is: GulabJammuns
table no is: 3
Total payable amount: 150
The keyword mutable is mainly used to allow a particular data member of const object
to be modified. When we declare a function as const, the this pointer passed to
function becomes const. Adding mutable to a variable allows a const pointer to change
members.
mutable is particularly useful if most of the members should be constant but a few
need to be updateable. Data members declared as mutable can be modified even
though they are the part of object declared as const. You cannot use the mutable
specifier with names declared as static or const, or reference.
This pointer:
The this pointer is passed as a hidden argument to all nonstatic member function calls
and is available as a local variable within the body of all nonstatic functions
this pointer is a constant pointer that holds the memory address of the current
object.
this pointer is not available in static member functions as static member functions
can be called without any object (with class name).
For a class X, the type of this pointer is X* const. Also, if a member function of X is
declared as const, then the type of this pointer is const X *const
When you have a class, it can have member functions of two types: static and nonstatic. The non-static member functions must operate on a particular instance of the
class, and they need to know where that instance is. To help them, the language
defines an implicit variable (i.e. one that is declared automatically for you when it is
needed without you having to do anything) which is called this and which will
automatically be made to point to the particular instance of the class on which the
member function is operating.
1) When local variables name is same as members name
#include<iostream>
using namespace std;
/* local variable is same as a member's name */
class Test
{
private:
int x;
public:
void setX (int x)
{
// The 'this' pointer is used to retrieve the object's x
// hidden by the local variable 'x'
this->x = x;
}
void print() { cout << "x = " << x << endl; }
};
int main()
{
Test obj;
int x = 20;
obj.setX(x);
obj.print();
return 0;
}
Output:
x = 20
When a reference to a local object is returned, the returned reference can be used to chain
function calls on a single object.
#include<iostream>
using namespace std;
class Test
{
private:
int x;
int y;
public:
Test(int x = 0, int
Test &setX(int a) {
Test &setY(int b) {
void print() { cout
};
int main()
{
Test obj1(5, 5);
y = 0) { this->x = x; this->y = y; }
x = a; return *this; }
y = b; return *this; }
<< "x = " << x << " y = " << y << endl; }
Output:
x = 10 y = 20
Output:
Constructor is executed
Destructor is executed (Temp obj
destroyed by compiler)
Constructor is executed
Destructor is executed
Destructor is executed
Final Specifier:
Used to prevent derived class to override the base class virtual function.
#include <iostream>
using namespace std;
class Base
{
public:
virtual void myfun() final
{
cout << "myfun() in Base";
}
};
class Derived : public Base
{
void myfun()
{
cout << "myfun() in Derived\n";
}
};
int main()
{
Derived d;
Base &b = d;
b.myfun();
return 0;
}
Output:
prog.cpp:14:10: error: virtual function virtual void
Derived::myfun()
void myfun()
^
prog.cpp:7:18: error: overriding final function virtual
void Base::myfun()
virtual void myfun() final
If a class or struct is marked as final then it becomes non inheritable and it cannot be
used as base class/struct.
#include <iostream>
class Base final
{
};
class Derived : public Base
{
};
int main()
{
Derived d;
return 0;
}
Output:
error: cannot derive from final base Base in derived
type Derived
class Derived : public Base
Initializer List:
Initializer List is used to initialize data members of a class. The list of members to be initialized
is indicated with constructor as a comma separated list followed by a colon.
lass Point {
private:
int x;
int y;
public:
Point(int i = 0, int j = 0):x(i), y(j) {}
int getX() const {return x;}
int getY() const {return y;}
};
int main() {
Point t1(10, 15);
cout<<"x = "<<t1.getX()<<", ";
cout<<"y = "<<t1.getY();
return 0;
}
The above code is just an example for syntax of Initializer list. In the above code, x and y can
also be easily initialed inside the constructor. But there are situations where initialization of
data members inside constructor doesnt work and Initializer List must be used.
1) For initialization of non-static const data members:
#include<iostream>
using namespace std;
class Test {
const int t;
public:
Test(int t):t(t) {} //Initializer list must be used
int getT() { return t; }
};
int main() {
Test t1(10);
cout<<t1.getT();
return 0;
}
If class A had both default and parameterized constructors, then Initializer List
is not must if we want to initialize a using default constructor, but it is must
to initialize a using parameterized constructor.
4) For initialization of base class members
#include <iostream>
using namespace std;
class A {
int i;
public:
A(int );
};
A::A(int arg) {
i = arg;
cout << "A's Constructor called: Value of i: " << i <<
endl;
}
// Class B is derived from A
class B: A {
public:
B(int );
};
B::B(int x):A(x) { //Initializer list must be used
cout << "B's Constructor called";
}
int main() {
B obj(10);
return 0;
}
variable = a;
3. And then finally destructor of Type is called for a since it goes out of scope.
Now consider the same code with MyClass() constructor with Initializer List
Deriving a class publicly guarantees this, as all the public data and methods from the
base class remain public in the derived class.
Everything that was protected in the base class remains protected in the derived class.
And, those things that were private in the base class are not directly accessible in the
derived class.
Polymorphism
The ability to use an operator or function in different ways in other words giving different
meaning or functions to the operators or functions is called polymorphism. Poly refers to
many. That is a single function or an operator functioning in many ways different upon the
usage is called polymorphism.
Static vs. dynamic binding:
Binding means connecting the function call to a function implementation.
Static Binding:
By default, matching of function call with the correct function definition happens at compile
time. This is called static binding or early binding or compile-time binding. Static binding is
achieved using function overloading & operator overloading. Even though there are two or
more functions with same name, compiler uniquely identifies each function depending on the
parameters passed to those functions.
Dynamic Binding:
C++ provides facility to specify that the compiler should match function calls with the correct
definition at the run time; this is called dynamic binding or late binding or run-time binding.
Dynamic binding is achieved using virtual functions. Base class pointer points to derived class
object. And a function is declared virtual in base class, then the matching function is identified
at run-time using virtual table entry.
Overloading vs. overriding Overriding of functions occurs when one class is inherited from another class.
Overloading can occur without inheritance.
Overloaded functions must differ in function signature ie either number of parameters
or type of parameters should differ. In overriding, function signatures must be same.
Overridden functions are in different scopes; whereas overloaded functions are in
same scope.
Overriding is needed when derived class function has to do some added or different
job than the base class function.
Overloading is used to have same name functions which behave differently depending
upon parameters passed to them.
Virtual Functions Runtime polymorphism:
#include<iostream>
using namespace std;
class Base
{
public:
virtual void show() { cout<<" In Base \n"; }
};
class Derived: public Base
{
public:
void show() { cout<<"In Derived \n"; }
};
int main(void)
{
Base *bp = new Derived;
bp->show(); // RUN-TIME POLYMORPHISM
return 0;
}
Output:
In Derived
Virtual functions are called according to the type of object pointed or referred, not
according to the type of pointer or reference. In other words, virtual functions are
resolved late, at runtime.
A destructor can be virtual. We may want to call appropriate destructor when a base
class pointer points to a derived class object and we delete the object. If destructor is
not virtual, then only the base class destructor may be called.
There is nothing like Virtual Constructor. Making constructors virtual doesn't make
sense as constructor is responsible for creating an object and it cant be delegated to
any other object by virtual keyword means.
We can have pointers or references of abstract classes but not an instance (object)
Virtual functions allow us to create a list of base class pointers and call methods of any
of the derived classes without even knowing kind of derived class object.
Compiler maintains two things to this magic:
o vtable: A table of function pointers. It is maintained per class.
o vptr: A pointer to vtable. It is maintained per object
Compiler adds additional code at two places to maintain and use vptr.
1) Code in every constructor. This code sets vptr of the object being created. This
code sets vptr to point to vtable of the class.
2) Code with polymorphic function call (e.g. bp->show() in above code).
Wherever a polymorphic call is made, compiler inserts code to first look for
vptr using base class pointer or reference (In the above example, since pointed
or referred object is of derived type, vptr of derived class is accessed). Once
vptr is fetched, vtable of derived class can be accessed. Using vtable, address
of derived class function show() is accessed and called.
Pure Virtual Function:
o If we don't override the pure virtual function in derived class, then derived
class also becomes abstract class. Compilation error.
o Pure virtual function is the function in the base class with no body. Since no
body, you have to add the notation =0 for declaration of the pure virtual
function in the base class.
o The base class with pure virtual function can't be instantiated since there is no
definition of the function in the base class. It is necessary for the derived class
to override pure virtual function. This type of class with one or more pure
virtual function is called abstract class which can't be instantiated, it can only
be inherited.
o Pure virtual destructor are legal in standard C++ and one of the most
important thing is that if class contains pure virtual destructor it is must to
provide a function body for the pure virtual destructor.
o Because destructors are always called in the reverse order of the class
derivation. That means derived class destructor will be invoked first & then
base class destructor will be called. If definition for the pure virtual destructor
is not provided then what function body will be called during object
destruction?
Overloading:
The concept of overloading is also a branch of polymorphism. When the exiting operator or
function is made to operate on new data type, it is said to be overloaded.
Each definition of an overloaded function must have a unique signature.
long GetTime (void); // seconds from midnight
void GetTime (int &hours, int &minutes, int &seconds);
Overloading means providing multiple definitions of
Function overloading is appropriate for:
Defining functions which essentially do the same thing, but operate on different
data types.
Providing alternate interfaces to the same function.
Each definition of an overloaded function must have a unique signature.
C++ allows the programmer to define additional meanings for its predefined operators
by overloading them.
Five operators cannot be overloaded:
.
.*
::
?:
sizeof
class Point {
public:
Point (int x, int y) {Point::x = x; Point::y = y;}
Point operator + (Point &p) {return Point(x + p.x,y + p.y);}
Point operator - (Point &p) {return Point(x - p.x,y - p.y);}
private:
int x, y;
};
After this definition, + and - can be used for adding and subtracting points, much in the same
way as they are used for adding and subtracting numbers:
Point p1(10,20), p2(10,20);
Point p3 = p1 + p2;
Point p4 = p1 - p2;
private:
int x, y;
};
The use of an overloaded operator is equivalent to an explicit call to the function which
implements it. For example:
operator+(p1, p2) // is equivalent to: p1 + p2
Setting a bit
Use the bitwise OR operator (|) to set a bit.
number |= 1 << x;
That will set bit x.
Clearing a bit
Use the bitwise AND operator (&) to clear a bit.
number &= ~(1 << x);
That will clear bit x. You must invert the bit string with the bitwise NOT operator ( ~),
Toggling a bit
The XOR operator (^) can be used to toggle a bit.
number ^= 1 << x;
Checking a bit
You didn't ask for this but I might as well add it.
To check a bit, shift the number x to the right, then bitwise AND it:
bit = (number >> x) & 1;
That will put the value of bit x into the variable bit.