The document is the course syllabus for C++ subject in the 2nd semester of B Sc IT program. It lists the following key topics to be covered: Function overloading, Operator overloading, Inheritance, Different forms of inheritance, Constructors and Destructors in inheritance, Virtual base class, Pointer to base class, Dynamic polymorphism, Virtual functions, Type conversions.
This set of slides introduces the reader to the concept of operator overloading for user-defined types in C++ (with elements of C++11 and C++14). The exemplary case of the complex class is introduced. It follows a discussion on how to implement mixed-mode arithmetic, which requires mixing member and non-member operator functions. Moreover, the technical tool of friend functions and access functions is discussed.
Operator overloading is a technique by which operators used in a programming language are implemented in user-defined types with customized logic that is based on the types of arguments passed.
This presentation is Unary operator overloading(prefix).
Here ,I try to describe how to Unary operator overloaded and its types with example. may be you can happily read this.
This set of slides introduces the reader to the concept of operator overloading for user-defined types in C++ (with elements of C++11 and C++14). The exemplary case of the complex class is introduced. It follows a discussion on how to implement mixed-mode arithmetic, which requires mixing member and non-member operator functions. Moreover, the technical tool of friend functions and access functions is discussed.
Operator overloading is a technique by which operators used in a programming language are implemented in user-defined types with customized logic that is based on the types of arguments passed.
This presentation is Unary operator overloading(prefix).
Here ,I try to describe how to Unary operator overloaded and its types with example. may be you can happily read this.
A talk from CppEurope 2019 about functional programming in C++.
It talks about lambdas, immutability, operations with functions (partial application, currying, functional composition), shows an example and ends with a procedure for refactoring legacy code.
The term overloading means ‘providing multiple definitions of’. Overloading of functions involves defining distinct functions which share the same name, each of which has a unique signature. 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.
Function overloading is purely a programming convenience.
Operators are similar to functions in that they take operands (arguments) and return a value. Most of the built-in C++ operators are already overloaded. For example, the + operator can be used to add two integers, two reals, or two addresses. Therefore, it has multiple definitions. The built-in definitions of the operators are restricted to built-in types. Additional definitions can be provided by the programmer so that they can also operate on user-defined types. Each additional definition is implemented by a function.
If any class have multiple functions with same names but different parameters then they are said to be overloaded. Function overloading allows you to use the same name for different functions, to perform, either same or different functions in the same class.
If you have to perform one single operation but with different number or types of arguments, then you can simply overload the function.
Functions in C++, this presentation will cover the following topics
• Functions
• Functions Basics
• Overloaded functions
o Different numbers of arguments
o Different kinds of arguments
Revision Fucntion overloading
• Inline functions
• Default arguments
Operator overloading can transform complex, obscure program listings into intuitively obvious ones. For examples, statements like :
ob3.addobjects ( ob1, ob2) or ob3 = ob1.addobjects( ob2) can be changed to the much more readable like ob3 = ob1 + ob2.
Note : The process of selecting the most appropriate overloaded function or operator is called overload resolution.
Operator Overloading
The keyword Operator
Overloading Unary Operator
Operator Return Type
Overloading Assignment Operator (=)
Rules for Overloading Operators
Inheritance
Reusability
Types of Inheritance
Virtual Base Classes
Object as a Class Member
Abstract Classes
Advantages of Inheritance
Disadvantages of Inheritance
It tells about functions in C++,Types,Use,prototype,declaration,Arguments etc
function with
A function with no parameter and no return value
A function with parameter and no return value
A function with parameter and return value
A function without parameter and return value
Call by value and address
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Albert Hoitingh
In this session I delve into the encryption technology used in Microsoft 365 and Microsoft Purview. Including the concepts of Customer Key and Double Key Encryption.
UiPath Test Automation using UiPath Test Suite series, part 3DianaGray10
Welcome to UiPath Test Automation using UiPath Test Suite series part 3. In this session, we will cover desktop automation along with UI automation.
Topics covered:
UI automation Introduction,
UI automation Sample
Desktop automation flow
Pradeep Chinnala, Senior Consultant Automation Developer @WonderBotz and UiPath MVP
Deepak Rai, Automation Practice Lead, Boundaryless Group and UiPath MVP
State of ICS and IoT Cyber Threat Landscape Report 2024 previewPrayukth K V
The IoT and OT threat landscape report has been prepared by the Threat Research Team at Sectrio using data from Sectrio, cyber threat intelligence farming facilities spread across over 85 cities around the world. In addition, Sectrio also runs AI-based advanced threat and payload engagement facilities that serve as sinks to attract and engage sophisticated threat actors, and newer malware including new variants and latent threats that are at an earlier stage of development.
The latest edition of the OT/ICS and IoT security Threat Landscape Report 2024 also covers:
State of global ICS asset and network exposure
Sectoral targets and attacks as well as the cost of ransom
Global APT activity, AI usage, actor and tactic profiles, and implications
Rise in volumes of AI-powered cyberattacks
Major cyber events in 2024
Malware and malicious payload trends
Cyberattack types and targets
Vulnerability exploit attempts on CVEs
Attacks on counties – USA
Expansion of bot farms – how, where, and why
In-depth analysis of the cyber threat landscape across North America, South America, Europe, APAC, and the Middle East
Why are attacks on smart factories rising?
Cyber risk predictions
Axis of attacks – Europe
Systemic attacks in the Middle East
Download the full report from here:
https://sectrio.com/resources/ot-threat-landscape-reports/sectrio-releases-ot-ics-and-iot-security-threat-landscape-report-2024/
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Jeffrey Haguewood
Sidekick Solutions uses Bonterra Impact Management (fka Social Solutions Apricot) and automation solutions to integrate data for business workflows.
We believe integration and automation are essential to user experience and the promise of efficient work through technology. Automation is the critical ingredient to realizing that full vision. We develop integration products and services for Bonterra Case Management software to support the deployment of automations for a variety of use cases.
This video focuses on the notifications, alerts, and approval requests using Slack for Bonterra Impact Management. The solutions covered in this webinar can also be deployed for Microsoft Teams.
Interested in deploying notification automations for Bonterra Impact Management? Contact us at sales@sidekicksolutionsllc.com to discuss next steps.
Elevating Tactical DDD Patterns Through Object CalisthenicsDorra BARTAGUIZ
After immersing yourself in the blue book and its red counterpart, attending DDD-focused conferences, and applying tactical patterns, you're left with a crucial question: How do I ensure my design is effective? Tactical patterns within Domain-Driven Design (DDD) serve as guiding principles for creating clear and manageable domain models. However, achieving success with these patterns requires additional guidance. Interestingly, we've observed that a set of constraints initially designed for training purposes remarkably aligns with effective pattern implementation, offering a more ‘mechanical’ approach. Let's explore together how Object Calisthenics can elevate the design of your tactical DDD patterns, offering concrete help for those venturing into DDD for the first time!
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Tobias Schneck
As AI technology is pushing into IT I was wondering myself, as an “infrastructure container kubernetes guy”, how get this fancy AI technology get managed from an infrastructure operational view? Is it possible to apply our lovely cloud native principals as well? What benefit’s both technologies could bring to each other?
Let me take this questions and provide you a short journey through existing deployment models and use cases for AI software. On practical examples, we discuss what cloud/on-premise strategy we may need for applying it to our own infrastructure to get it to work from an enterprise perspective. I want to give an overview about infrastructure requirements and technologies, what could be beneficial or limiting your AI use cases in an enterprise environment. An interactive Demo will give you some insides, what approaches I got already working for real.
Connector Corner: Automate dynamic content and events by pushing a buttonDianaGray10
Here is something new! In our next Connector Corner webinar, we will demonstrate how you can use a single workflow to:
Create a campaign using Mailchimp with merge tags/fields
Send an interactive Slack channel message (using buttons)
Have the message received by managers and peers along with a test email for review
But there’s more:
In a second workflow supporting the same use case, you’ll see:
Your campaign sent to target colleagues for approval
If the “Approve” button is clicked, a Jira/Zendesk ticket is created for the marketing design team
But—if the “Reject” button is pushed, colleagues will be alerted via Slack message
Join us to learn more about this new, human-in-the-loop capability, brought to you by Integration Service connectors.
And...
Speakers:
Akshay Agnihotri, Product Manager
Charlie Greenberg, Host
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf91mobiles
91mobiles recently conducted a Smart TV Buyer Insights Survey in which we asked over 3,000 respondents about the TV they own, aspects they look at on a new TV, and their TV buying preferences.
Neuro-symbolic is not enough, we need neuro-*semantic*Frank van Harmelen
Neuro-symbolic (NeSy) AI is on the rise. However, simply machine learning on just any symbolic structure is not sufficient to really harvest the gains of NeSy. These will only be gained when the symbolic structures have an actual semantics. I give an operational definition of semantics as “predictable inference”.
All of this illustrated with link prediction over knowledge graphs, but the argument is general.
Accelerate your Kubernetes clusters with Varnish CachingThijs Feryn
A presentation about the usage and availability of Varnish on Kubernetes. This talk explores the capabilities of Varnish caching and shows how to use the Varnish Helm chart to deploy it to Kubernetes.
This presentation was delivered at K8SUG Singapore. See https://feryn.eu/presentations/accelerate-your-kubernetes-clusters-with-varnish-caching-k8sug-singapore-28-2024 for more details.
Accelerate your Kubernetes clusters with Varnish Caching
3d7b7 session4 c++
1. Course Name- B Sc IT
Subject Name - C++
Semester - II
Neetu Gupta
1
2. Contents
• Function overloading
• Operator overloading
• Inheritance
• Different forms of inheritance
• Constructors and
• Destructors in inheritance
• Virtual base class
3. Contents
• Virtual base class
• Pointer to base class
• Dynamic polymorphism
• Virtual functions
• Type conversions
4. Function overloading
• In C we can have only one function with a
given name.
• But, in C++ we have a feature to declare
more than one function with the same
name as long as they have different
signatures i.e. parameters.
• The difference in parameters could be
either in number or type or both.
5. • Function overloading is the practice of declaring
the same function with different signatures.
• The same function name will be used with
different number of parameters and parameters
of different type. But overloading of functions
with different return types are not allowed.
• You overload a function name f by declaring
more than one function with the name f in the
same scope. The declarations of f must differ
from each other by the types and/or the number
of arguments in the argument list.
6. • For examples we can have following functions in a c++ program
void Add(int x, int y)
{
cout<<" Integer addition result: "<<(x+y);
}
void Add(double x, double y)
{
cout<< " Double addition result: "<<(x+y);
}
void Add(float x, float y)
{
cout<< " float addition result: "<<(x+y);
}
Three functions with same name i.e. Add(..) but differ in types
7. Calling an overloaded function
• When we call an overloaded function, the
correct function is selected by comparing
the argument list of the function call with
the parameter list of each of the
overloaded functions.
• The function i.e. actually called depends
upon the arguments we pass at the time of
function call statement.
• This is an example of static polymorphism
8. int main() {
Add (10,10);
Add (10.10d, 10.5d);
Add (10.10f, 10.5f);
}
• Add (10,10); calls the function void Add (int x,
int y)
• Add (10.10d, 10.5d); calls the function void
Add (double x, double y)
• Add (10.10f, 10.5f); calls the function void Add
(float x, float y)
9. • Remember function overloaded can not be
done on the basis of return type.
• For example following functions will give
error, as both the functions are same as
they only differ in return type:
void Add(int x, int y)
int Add(int x, int y)
10. Operator overloading
• C++ CVectororporates the option to use
standard operators to perform operations with
classes in addition to with fundamental types.
For example,
int a, b, c;
a = b + c;
• This is obviously valid code in C++, sCVectore
the different variables of the addition are all
fundamental types.
11. • But if we have a code like
• class Product {
string name;
float price;
};
Product prod1, prod2, prod3;
prod3 = prod1 + prod2; // Compilation error
• The above code will not work, as the compiler does
not on how to apply + on Product type variables i.e.
prod1 and prod2 here.
12. • Using C++ feature to overload operators,
we can design classes able to perform
operations using standard operators.
• Here is a list of all the operators that can
be overloaded:
+ - * / = < > += -= *= /=
<< >> <<= >>= == != <= >=
++ --
%&^!|~
&= ^= |= && || %= [] () , -> * ->
new delete new[] delete[]
13. • To overload an operator in order to use it with
classes we declare operator functions, which are
regular functions whose names are the operator
keyword followed by the operator sign that we
want to overload.
• The format is will be as:
type operator sign (parameters) {
/*...*/
}
14. • Example
#CVectorlude <iostream>
using namespace std;
class CVector {
public: int x, y;
CVector () {}; // default constructor
CVector (int,int); // constructor
CVector operator + (CVector); // + operator overloaded
};
CVector: CVector (int a, int b) {
x = a; y = b;
}
CVector CVector::operator+ (CVector param) {
CVector temp;
temp.x = x + param.x;
temp.y = y + param.y;
return (temp);
}
15. Here you have an example that overloads the
addition operator (+).
• We are going to create a class to store
bidimensional vectors
• X represents x-coordinate and y represents y-
coordinate value for a CVector.
• The addition of two bidimensional vectors is an
operation as simple as adding the two x
coordinates to obtain the resulting x coordinate
and adding the two y coordinates to obtain the
resulting y.
16. • Now see how can we use the class CVector as
int main () {
CVector a (3,1);
CVector b (1,2);
CVector c;
c = a + b;
cout << c.x << "," << c.y;
return 0;
}
17. • Notice the below two methods
CVector (int, int); // function name CVector (constructor)
CVector operator+ (CVector); // function returns a CVector
• The function operator+ of class
CVector is the one that is in charge of
overloading the addition operator (+).
• This function of class CVector can be
called either implicitly using the operator,
or explicitly using the function name
18. c = a + b; // using the operator
c = a.operator+ (b); // using the function name
• Both these expressions are equivalent
and will call the +operator function defined
in class CVector.
• This way we can overload any binary
operator in c++ like - , /, % etc.
19. Unary operator overloading
We can overload unary operator using two ways
as
• with either a nonstatic member function that has
no parameters
return_type operator@()
• Or with a nonmember function that has one
parameter
return_type operator@(T)
Here,
@ could be any unary opeartor and T is a type.
return_type could be any type
20. Add the following function to class CVector
declared before
CVector CVector::operator! () {
CVector temp;
temp.x = !x;
temp.y = !y;
return (temp);
}
Here operator ! Is overloaded and define a
behavior for class CVector.
21. The above code can be use in main()
function as
int main() {
CVector ox(10,30);
CVector oy = !ox // function operator! Is called
}
22. • Overloading decrement (--) and
CVectorrement(++) operators is different
• SCVectore ++ and – have different
meanings for postfix and prefix we should
override both forms.
• For this we should add two set of functions
like
// Operator Function Definition for prefix
type operator ++ ();
type operator -- ();
23. // Operator Function Definition for postfix
type operator ++ (int);
type operator -- (int);
Here we make use of a dummy argument.
• As you can see in this case we use int as a
dummy argument for post-fix, when we redefine
the functions for the unary CVectorrement (++)
and decrement (--) overloaded operators.
• You must remember that int isn't an integer, but
just a dummy argument. You can see it as a
signal to the compiler to create the post-fix
notation of the operator.
24. • Two functions for ++ operator in class
CVector could be as below:
CVector operator ++ () {
// Operator Function Definition for prefix
return CVector (++x, ++y);
}
CVector operator ++ (int) {
// Operator Function Definition with dummy
//argument for postfix
return CVector (x++, y++);
}
25. • Similarly, Two functions for -- operator in
class CVector could be as below:
CVector operator -- () {
// Operator Function Definition for prefix
return CVector(--x, --y);
}
CVector operator -- (int) {
// Operator Function Definition with dummy
//argument for postfix
return CVector (x--, y--);
}
26. Remember
• In operator overloading always remember:
2. We can not change the precedence and
associatively of operators even if we overload
them in a class.
3. Few operators can not be overloaded like :
• scope resolution operator - ::
• sizeof operator
• Conditional operator (?:)
• class member access operators (.,.*)
27. Type conversion
• Type Conversion is the process of
converting one type into another.
• In other words converting an expression
of a given type into another is called type
casting or conversion
• There are two ways
• Automatic Conversion otherwise called as
Implicit Conversion
• Type casting otherwise called as Explicit
Conversion
28. Implicit Type Conversion
• This is automatic conversion, which is not
done using any operator or function.
• The value gets automatically converted to
the specific type in which it is assigned.
• Looking at the expression, the compiler
automatically converts an expression of
one type into another type
29. • For example
#include <iostream.h>
void main()
{
short x=6000;
int y;
y=x;
}
• In the above example the data type short namely
variable x is converted to int and is assigned to
the integer variable y.
30. • However, some type conversions are
inherently unsafe, and if the compiler can
detect that an unsafe conversion is being
implicitly requested, it will issue a warning.
• For example if we write the code as below
int nValue = 3.14156; // implicit conversion to integer value 3
Here the fractional part of the double value
3.14156 is dropped because int type can not
support fractional values.
31. • Because converting a double to an int
usually causes data loss (making it
unsafe), compilers such as Visual Studio
Express 2005 will typically issue a
warning.
• Few unsafe automatic conversions could
be
– assigning unsigned variables to signed
variables (and vice-versa),
– assigning large integers (eg. a 4-byte long) to
integer variables of a smaller size (eg. a 2-
byte short).
32. Explicit Conversion
• Explicit conversion can be done using type cast
operator and the general syntax for doing this is
datatype (expression);
• Here in the above datatype is the type which the
programmer wants the expression to gets
changed
• This is called c++ style casting
33. #include <iostream.h>
void main()
{
int a;
float b,c;
cout<< “Enter the value of a:”;
cin>>a;
cout<< “n Enter the value of b:”;
cin>>b;
c = float(a)+b;
cout<<”n The value of c is:”<<c;
}
Output is
Enter the value of a: 10
Enter the value of b: 12.5
The value of c is: 22.5
•
34. • In the above program a is declared as integer
and b and c are declared as float. In the type
conversion statement namely
c = float (a) + b;
• The variable a of type integer is converted into
float type and so the value 10 is converted as
10.0 and then is added with the float variable b
with value 12.5 giving a resultant float variable c
with value as 22.5
35. Inheritance
• Inheritance allows one data type to
acquire properties of other data types.
• Inheritance allows to create classes which are
derived from other classes, so that they
automatically include some of its "parent's"
members, plus its own.
• The original class is called the base class and
the new class created using base class is called
derived class.
36. • For example, we are going to suppose that we want to
declare a series of classes that describe polygons like
our CRectangle, or like CTriangle. They have certain
common properties, such as both can be described by
means of only two sides: height and base.
• This could be represented in the world of classes with a
class CPolygon from which we would derive the two
other ones: CRectangle and CTriangle.
• The class CPolygon would contain
members that are common for both types
of polygon. In our case: width and height.
And CRectangle and CTriangle would be
its derived classes, with specific features
that are different from one type of polygon
to the other.
37. NEED FOR INHERITANCE
• Capability to express the inheritance
relationship-This ensures the closeness with the
real world models.
• Reusability-The advantage of reusability are:
faster development time and easier
maintenance.
• Transitive nature of inheritance-If a class B
inherits properties of another class A then all
subclasses of B will automatically inherits the
properties of A. This property is called transitive
nature of inheritance.
38. Syntax
• In order to derive a class from another, we
use a colon (:) in the declaration of the
derived class using the following format:
class derived_class_name: public base_class_name
{ /*...*/
};
Here derived_class_name is the name of
the derived class and base_class_name is
the name of the class on which it is based.
39. // Example derived classes
#include <iostream>
using namespace std;
class CPolygon {
protected:
int width, height;
public:
void set_values (int a, int b) {
width=a; height=b;
}
};
class CRectangle: public CPolygon {
public: int area () {
return (width * height);
}
};
class CTriangle: public CPolygon {
public: int area () {
return (width * height / 2);
}
};
40. • We can use the above created classes as
int main () {
CRectangle rect;
CTriangle trgl;
rect.set_values (4,5);
trgl.set_values (4,5);
cout << rect.area() << “n”;
cout << trgl.area() << “n”;
return 0;
}
• The objects of the classes CRectangle and CTriangle each contain
members inherited from CPolygon. These are: width, height and
set_values().
• That’s is why we are using these members in main() method on the
objects of classes CRectangle and CTriangle.
41. • In CPolygon Class we used protected access specifier
• The protected access specifier is similar to private. Its
only difference occurs in fact with inheritance.
• When a class inherits from another one, the members of
the derived class can access the protected members
inherited from the base class, but not its private
members.
• Since we wanted width and height to be accessible from
members of the derived classes CRectangle and
CTriangle and not only by members of CPolygon, we
have used protected access instead of private.
42. • We can summarize the different access types according to who
can access them in the following way:
Access public protected Private
members of the yes yes yes
same class
members of the yes yes no
derived class
not members yes no no
• Here "not members" represent any access
from outside the class, such as from main(),
from another class or from a function.
43. protected inheritance
• So far we have code written like
class B : public A {}
This means that the class B is publicily derived
from B.
• We can specify protected derivation as well as
class B : protected A {}
• If we specify a more restrictive access level like
protected, all public members of the base class
are inherited as protected in the derived class.
44. • For example, if we write the code as
class CRectangle: protected CPolygon
{ ... }
• Then the function set_values() defined
public in CPolygon will become
protected in class CRectangle and we
can not write code like
CRectangle rect;
rect.set_values (4,5); // Error
45. private inheritance
• As we can have public and protected base class,
we can also have private base class.
• We can specify private derivation as well as
class B : private A {}
• If we specify a more restrictive access level like
private, all public and protected members of the
base class are inherited as private in the derived
class.
46. • For example, if we write the code as
class CRectangle: private CPolygon {
public: int area () {
return (width * height);
}
};
The above code will not compile, because
• We are inheriting CPolygon as private
base class, hence the protected members
width & height become private
47. Types of Inheritance
• Single Inheritance
- When a subclass
inherits only from
one base class,it is
known as single
inheritance.
class B: public A {
}
48. • Multiple Inheritance -
When a subclass
inherits from multiple
base classes, it is
known as multiple
inheritance.
class C: public A,
public B {
}
49. • Hierarchical Inheritance - When many
sub classes inherits from a single base
class,it is known as hierarchical
inheritance.
50. • Multilevel Inheritance - When a subclass
inherits from a class that itself inherits from
another class,it is known as multilevel
inheritance.
class B: public A {
}
class C : public B {
}
51. • Hybrid Inheritance - When a subclass
inherits from multiple base classes and all
of its base classes inherits from a single
base class,this form of inheritance is
known as hybrid inheritance.
52. Constructors & inheritance
• Suppose I have a class B derived from A as
class B : public A {
public:
B () {};
B (int i) {};
}
• If I create an object as
B b;
Then how the constructor of class A is called as we
are creating the object of class B only?
53. The rule is :
• Whenever we create an object of derived
class then constructor of base is called
automatically even if we do not call them
explicitly.
• If we are using multilevel inheritance then
the call to constructor is starting from the
first base class till the most derived class.
54. // Example
class A {
public:
A () {
cout << “In A’s Constructor n”;
}
}
class B : public A {
public:
B () {
cout << “In B’s Constructor n”;
}
}
class C : public B {
public:
C () {
cout << “In C’s Constructor n”;
}
}
55. main() {
C c;
}
Output will be
In A’s Constructor
In B’s Constructor
In C’s Constructor
Here we are creating an object of class C, so the
constructor of class A is called first, then B and
then C.
56. Destructor
• Like constructor, destructor of base is
called automatically when the object of
derived class s destroyed or deleted or
goes out of scope
• But the destructors are called in reverse
order of the constructor call.
• The destructor of derived is called first,
then of its base class and so on.
57. // Example
class A {
public:
A () {
cout << “In A’s Constructor n”;
}
~A () {
cout << “In A’s Destructor n”;
}
}
class B : public A {
public:
B () {
cout << “In B’s Constructor n”;
}
~B () {
cout << “In B’s Destructor n”;
}
}
class C : public B {
public:
C () {
cout << “In C’s Constructor n”;
}
~C () {
cout << “In C’s Destructor n”;
}
}
58. main() {
C c;
}
Output will be
In A’s Constructor
In B’s Constructor
In C’s Constructor
In C’s Destructor
In B’s Destructor
In A’s Destructor
59. Multiple inheritance and ambiguity
• We can inherit a class form more than one class and call
id multiple inheritance.
• Consider a inheritance situation as below:
A
member - i
B : public A C : public A
member – i of A member – i of A
D : public B,C
member – I of A via B
Member – I of A via C
60. • Here, the class D is derived form B and C. And
both B and C are derived from A.
• That means we have two copy of class A in class
D.
• When we create an object of class D, there are
two i of A, one instance via class B and other
instance of i via class C.
• If I write a code like:
D d;
d.i; // Error
Compiler is not able to resolve i in D as it has its
two instances.
61. Virtual base class
• Duplication of inherited members due to
these multiple paths can be avoided by
making the common base class as virtual
base class while declaring the direct or
intermediate base clases.
• Like we can declare the A as virtual base
class when we inherit the A in B and C
62. // Example
class A {
public:
int i;
}
class B : public virtual A {
………..
}
class C : public virtual A {
………..
}
class D : public C,D {
………..
}
63. Virtual functions
• Before understanding the virtual fucntions, lets
take a look at polymorphism.
• Pointers to base class
– One of the key features of derived classes is that a
pointer to a derived class is type-compatible with a
pointer to its base class. Polymorphism is the art of
taking advantage of this simple but powerful and
versatile feature, that brings Object Oriented
Methodologies to its full potential.
64. // pointers to base class
#include <iostream>
using namespace std;
class CPolygon {
protected: int width, height;
public:
void set_values (int a, int b) {
width=a; height=b;
}
};
class CRectangle: public CPolygon {
public: int area () {
return (width * height);
}
};
class CTriangle: public CPolygon {
public:
int area () {
return (width * height / 2);
}
};
65. int main () {
CRectangle rect;
CTriangle trgl;
CPolygon * ppoly1 = ▭
CPolygon * ppoly2 = &trgl;
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
cout << rect.area() << endl;
cout << trgl.area() << endl;
return 0;
}
• In function main, we create two pointers that point to objects of class
CPolygon (ppoly1 and ppoly2). Then we assign references to rect
and trgl to these pointers, and because both are objects of classes
derived from CPolygon, both are valid assignment operations.
66. • The only limitation in using *ppoly1 and *ppoly2 instead
of rect and trgl is that both *ppoly1 and *ppoly2 are of
type CPolygon* and therefore we can only use these
pointers to refer to the members that CRectangle and
CTriangle inherit from CPolygon.
• For that reason when we call the area() members at the
end of the program we have had to use directly the
objects rect and trgl instead of the pointers *ppoly1 and
*ppoly2.
• In order to use area() with the pointers to class
CPolygon, this member should also have been declared
in the class CPolygon, and not only in its derived
classes, but the problem is that CRectangle and
CTriangle implement different versions of area, therefore
we cannot implement it in the base class. This is when
virtual members become handy.
67. Members declared as virtual
• A member of a class that can be redefined
in its derived classes is known as a virtual
member.
• In order to declare a member of a class as
virtual, we must precede its declaration
with the keyword virtual.
virtual returntype function_name (parameters)
68. // pointers to base class
#include <iostream>
using namespace std;
class CPolygon {
protected: int width, height;
public:
void set_values (int a, int b) {
width=a; height=b;
}
virtual int area () {
return (0);
}
};
class CRectangle: public CPolygon {
public: int area () {
return (width * height);
}
};
class CTriangle: public CPolygon {
public:
int area () {
return (width * height / 2);
}
};
69. • Now the three classes (CPolygon, CRectangle and CTriangle) have
all the same members: width, height, set_values() and area().
int main () {
CRectangle rect;
CTriangle trgl;
CPolygon poly;
CPolygon * ppoly1 = ▭
CPolygon * ppoly2 = &trgl;
CPolygon * ppoly3 = &poly;
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
ppoly3->set_values (4,5);
cout << ppoly1->area() << endl;
cout << ppoly2->area() << endl;
cout << ppoly3->area() << endl;
return 0;
}
70. • The member function area() has been declared as virtual
in the base class because it is later redefined in each
derived class.
• Now when we do the following
CRectangle rect;
CPolygon * ppoly1 = ▭
ppoly1->set_values (4,5);
cout << ppoly1->area() << endl;
Here the arear() method of appropriate class i.e. CRectangle is called because area() is
declared as virtual in base class.
• You can verify if you want that if you remove this virtual
keyword from the declaration of area() within CPolygon,
and then you run the program the result will be 0 for the
three polygons instead of 20, 10 and 0.
71. • That is because instead of calling the
corresponding area() function for each object
(CRectangle::area(), CTriangle::area() and
CPolygon::area(), respectively),
CPolygon::area() will be called in all cases since
the calls are via a pointer whose type is
CPolygon*.
• Rule is:
When a function is declared virtual in base class,
then the function call via base class pointer is
resolved at runtime and the function
called is of the class whose object it is.
72. • Therefore, what the virtual keyword does is to
allow a member of a derived class with the same
name as one in the base class to be
appropriately called from a pointer, and more
precisely when the type of the pointer is a
pointer to the base class but is pointing to an
object of the derived class, as in the above
example.
• A class that declares or inherits a virtual function
is called a polymorphic class.
• The resolving of function at runtime depending
upon the type of object is called dynamic
polymorphism.
73. Abstract base class
• Abstract base classes are something very similar to our
CPolygon class of our previous example.
• The only difference is that in our previous example we
have defined a valid area() function with a minimal
functionality for objects that were of class CPolygon (like
the object poly),
• whereas in an abstract base classes we could leave that
area() member function without implementation at all.
• This is done by appending =0 (equal to zero) to the
function declaration.
• An abstract base CPolygon class could look like this:
74. // abstract class CPolygon
class CPolygon {
protected: int width, height;
public:
void set_values (int a, int b)
{
width=a;
height=b;
}
virtual int area () =0;
};
• Notice how we appended =0 to virtual int area () instead of
specifying an implementation for the function. This type of
function is called a pure virtual function, and all classes that
contain at least one pure virtual function are abstract base
classes.
75. • Important : The main difference between an abstract base class and a
regular polymorphic class is that because in abstract base classes at least
one of its members lacks implementation we cannot create instances
(objects) of it.
• But a class that cannot instantiate objects is not totally useless. We can
create pointers to it and take advantage of all its polymorphic abilities.
Therefore a declaration like:
CPolygon poly;
would not be valid for the abstract base class we have just declared,
because tries to instantiate an object. Nevertheless, the following pointers
are valid:
CPolygon * ppoly1; CPolygon * ppoly2;
• This is so for as long as CPolygon includes a pure virtual function and
therefore it's an abstract base class. However, pointers to this abstract base
class can be used to point to objects of derived classes.
76. int main () {
CRectangle rect;
CTriangle trgl;
CPolygon * ppoly1 = ▭
CPolygon * ppoly2 = &trgl;
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
cout << ppoly1->area() << endl;
cout << ppoly2->area() << endl;
return 0;
}
• If you review the program you will notice that we refer to
objects of different but related classes using a unique
type of pointer (CPolygon*). This can be tremendously
useful and called dynamic polymorphism.