UNITII Constructor It is a function used to

  • Slides: 54
Download presentation
UNIT-II

UNIT-II

Constructor It is a function used to initialize the data of an object of

Constructor It is a function used to initialize the data of an object of a class ◦ Same name as class itself ◦ Cannot return anything, not even void ◦ A class may define more than one constructor With different parameter lists Default constructor has no parameters Called automatically ◦ When class object is declared as automatic variable ◦ By new operator

Destructor It is a function used to clean up an object of a class

Destructor It is a function used to clean up an object of a class prior to deleting that object Class name preceeded by '~' No parameters, no result Called automatically When function exits scope of automatic class object By delete operator

Example

Example

Cont…

Cont…

Dynamically created objects

Dynamically created objects

Cont…

Cont…

When do we make copies of an object? 1) When passing them to a

When do we make copies of an object? 1) When passing them to a function by value 2) When returning them from a function by value 3) When creating a new object that is initialized with a copy of an existing object 4) When assigning objects (x = y) 1. Items 1, 2 and 3 are handled by the copy constructor. 2. Item 4 is handled by overloading the assignment ( = ) operator. 8 CMSC 202, Version 3/02

What is a copy constructor? It’s a constructor – it’s used to construct new

What is a copy constructor? It’s a constructor – it’s used to construct new objects It does so by making a copy of an existing object We can do so explicitly // construct t 1 Time t 1 (12, 34, 56); // construct t 2 by copying t 1 Time t 2 (t 1); // construct t 3 by copying t 1 Time t 3 = t 1; The compiler may make copies when it needs them 9 CMSC 202, Version 3/02

Why haven’t we seen this before? The compiler provides a default copy constructor which

Why haven’t we seen this before? The compiler provides a default copy constructor which up until now has been sufficient. The default copy constructor simply copies each of the data members from the existing object into the new object This is not sufficient if one or more of the data members points to dynamically allocated memory 10 CMSC 202, Version 3/02

Copy Constructor A copy constructor is called whenever a new variable is created from

Copy Constructor A copy constructor is called whenever a new variable is created from an object. There are 3 important places where a copy constructor is called. When an object is created from another object of the same type When an object is passed by value as a parameter to a function When an object is returned from a function Copy constructor is a constructor function with the same name as the class. It is used to make deep copy of objects.

Copy constructor syntax The copy constructor takes a reference to a const parameter. It

Copy constructor syntax The copy constructor takes a reference to a const parameter. It is const to guarantee that the copy constructor doesn't change it, and it is a reference because a value parameter would require making a copy, which would invoke the copy constructor, which would make a copy of its parameter, which would invoke the copy constructor. Syntax classname { public: classname(const classname & objectname); }; classname: : classname(const classname &objectname) { //copy definition part }

Cont… By default, the compiler provides a copy constructor that performs a member-by-member copy

Cont… By default, the compiler provides a copy constructor that performs a member-by-member copy from the original object to the one being created. This is called a member wise, or shallow copy. Overloading Assigment ( = ) Operators work almost exactly like Copy Constructors, with a few subtle differences They need to check for self assignment They return a reference to *this Depending on your code, they may be different (more optimized) than your copy constructor

Virtual Functions Allow print in both employee and manager, with different definitions. C++ will

Virtual Functions Allow print in both employee and manager, with different definitions. C++ will “do the right thing”, based on the actual object class.

Virtual Functions (cont’d)

Virtual Functions (cont’d)

Virtual Functions (cont’d)

Virtual Functions (cont’d)

Virtual Functions (cont’d)

Virtual Functions (cont’d)

Understanding the Benefits of Overloading Having more than one function with the same name

Understanding the Benefits of Overloading Having more than one function with the same name is beneficial because you can use one easy-to-understand function name without paying attention to the data types involved Polymorphism allows the same operation to be carried out differently, depending on the object Some reserve the term polymorphism (or pure polymorphism) for situations in which one function body is used with a variety of arguments

Using the + Operator Polymorphically Separate actions can result from what seems to be

Using the + Operator Polymorphically Separate actions can result from what seems to be the same operation or command The + operator has a variety of meanings, which include: Alone before a value (called unary form), + indicates a positive values, as in the expression +7 Between two integers (called binary form), + indicates integer addition, as in the expression 5+ 9 Between two floating-point numbers (also called binary form), + indicates floating-point addition, as in the expression 6. 4 + 2. 1

Overloading Operators— The Rules Operator overloading is the process by which you apply operators

Overloading Operators— The Rules Operator overloading is the process by which you apply operators to your own abstract data types The +, -, *, and / symbols make it easy to work with built-in data types such as int and double Classes, however, contain a variety of data members As a result, if you want the compiler to perform arithmetic with two class objects, you must tell the compiler what you mean Good programming style dictates that you endow the operator with a reasonable meaning

Overloading Operators— The Rules You overload an operator by making it a function; subsequently,

Overloading Operators— The Rules You overload an operator by making it a function; subsequently, you can use it just like any other function C++ operators are classified as unary or binary, depending on whether they take one or two arguments, respectively

Binary Operators that Can Be Overloaded

Binary Operators that Can Be Overloaded

Overloading Operators— The Rules Associativity refers to the order in which actions within an

Overloading Operators— The Rules Associativity refers to the order in which actions within an expression are carried out You cannot change associativity when you overload operators You also cannot change the normal precedence of any operator

Overloading Operators— The Rules

Overloading Operators— The Rules

Overloading Output The << operator also is overloaded by C++ It is both a

Overloading Output The << operator also is overloaded by C++ It is both a bitwise left-shift operator and an output operator; it is called the insertion operator when used for output The << operator acts as an output operator only when cout (or another output stream object) appears on the left side When you use cout in a program, you must include #include<iostream. h> The preceding function, called operator<<(), returns a reference to ostream

Overloading Output It accepts two arguments: a reference to ostream (locally named out in

Overloading Output It accepts two arguments: a reference to ostream (locally named out in this example) and an integer (locally named in in this example) C++ overloads the << operator to work with the built-in data types; you also may overload the << operator to work with your own classes To overload << operator so it can work with a Sale object, you must add the overloaded operator <<() function to the Sale class

Overloading Output The operator <<() function is a friend to the class of the

Overloading Output The operator <<() function is a friend to the class of the object it wants to print out, e. g. Sale here.

Overloading Input If the << operator can be overloaded for output, it makes sense

Overloading Input If the << operator can be overloaded for output, it makes sense that the >> operator also can be overloaded for input The advantage of overloading operators such as >> is that the resulting programs look cleaner and are easier to read You can create an extraction operator, or operator>>() function, that uses istream (which is defined in iostream. h, along with ostream) by using a prototype as follows: friend istream& operator>>(istream &in, Sale &Sale);

Overloaded Operator>>() Function for the Sale Class

Overloaded Operator>>() Function for the Sale Class

Overloading Input Ex 8 -6

Overloading Input Ex 8 -6

Overloading ++ and - With C++, you use ++ to increment variables, and -

Overloading ++ and - With C++, you use ++ to increment variables, and - - to decrement variables When a prefix operator such as ++ is used in an expression, the mathematical operation takes place before the expression is evaluated When the postfix operator is used, the expression is evaluated before the mathematical operation takes place Within the operator ++() function in the Inventory class, you can write the statement that increases num. Sold in several different ways

Using the Prefix and Postfix ++ Operators with an Integer

Using the Prefix and Postfix ++ Operators with an Integer

The Inventory Class

The Inventory Class

8 Overloading ++ and - The statements num. Sold++; , num. Sold = num.

8 Overloading ++ and - The statements num. Sold++; , num. Sold = num. Sold +1; , and num. Sold += 1; all would work Ex 8 -8

Using Postfix Increment and Decrement Operators A problem arises if you want to use

Using Postfix Increment and Decrement Operators A problem arises if you want to use a postfix ++ operator as well as a prefix ++ operator with a class When you overload any C++ function, you must supply different argument lists; for the postfix ++ operator, you use an integer argument The Inventory class postfix operator ++() function prototype is: Inventory& operator++(int); Ex 8 -8

8 Overloading the = = Operator Writing an operator = =() function should be

8 Overloading the = = Operator Writing an operator = =() function should be an easy task You simply decide what will constitute equality in class members When you create your own classes, you choose whether equivalency means that every data field must be equivalent, or only specific data members The operator = =() function may return either an integer or a boolean variable representing true or false

Overloading the = = Operator A variable of type bool can hold one of

Overloading the = = Operator A variable of type bool can hold one of two values: true or false Some older C++ compilers do not support the bool type; with those compilers you would use the first version of operator = =() that returns an integer EX 8 -9

Overloading the = Operator The = operator can be overloaded for use with your

Overloading the = Operator The = operator can be overloaded for use with your own classes Unlike other operators, if you don’t define the = operator, C++ provides a definition for you If you want the = operator to do something other than assign each member, then you must create a customer operator=()function In addition, if the class contains data fields that are pointers, you should create a custom function EX 8 -9

Overloading [ ] and ( ) The subscript operator, operator[ ], is declared like

Overloading [ ] and ( ) The subscript operator, operator[ ], is declared like any other function, but called in a manner similar to accessing an array element You can include any instructions you want within an operator [ ] function Typically, you use this function to perform a task that both requires an argument and does not quite fit into another operator’s usual meaning

Understanding the Benefits of Overloading Having more than one function with the same name

Understanding the Benefits of Overloading Having more than one function with the same name is beneficial because you can use one easy-to-understand function name without paying attention to the data types involved Polymorphism allows the same operation to be carried out differently, depending on the object Some reserve the term polymorphism (or pure polymorphism) for situations in which one function body is used with a variety of arguments

Using the + Operator Polymorphically Separate actions can result from what seems to be

Using the + Operator Polymorphically Separate actions can result from what seems to be the same operation or command The + operator has a variety of meanings, which include: Alone before a value (called unary form), + indicates a positive values, as in the expression +7 Between two integers (called binary form), + indicates integer addition, as in the expression 5+ 9 Between two floating-point numbers (also called binary form), + indicates floating-point addition, as in the expression 6. 4 + 2. 1

Overloading Operators— The Rules Operator overloading is the process by which you apply operators

Overloading Operators— The Rules Operator overloading is the process by which you apply operators to your own abstract data types The +, -, *, and / symbols make it easy to work with built-in data types such as int and double Classes, however, contain a variety of data members As a result, if you want the compiler to perform arithmetic with two class objects, you must tell the compiler what you mean Good programming style dictates that you endow the operator with a reasonable meaning

Overloading Operators— The Rules You overload an operator by making it a function; subsequently,

Overloading Operators— The Rules You overload an operator by making it a function; subsequently, you can use it just like any other function C++ operators are classified as unary or binary, depending on whether they take one or two arguments, respectively

Binary Operators that Can Be Overloaded

Binary Operators that Can Be Overloaded

Overloading Operators— The Rules Associativity refers to the order in which actions within an

Overloading Operators— The Rules Associativity refers to the order in which actions within an expression are carried out You cannot change associativity when you overload operators You also cannot change the normal precedence of any operator

Overloading Operators— The Rules

Overloading Operators— The Rules

Type conversion Reference conversions A reference conversion can be performed wherever a reference initialization

Type conversion Reference conversions A reference conversion can be performed wherever a reference initialization occurs, including reference initialization done in argument passing and function return values. A reference to a class can be converted to a reference to an accessible base class of that class as long as the conversion is not ambiguous. The result of the conversion is a reference to the base class subobject of the derived class object. Reference conversion is allowed if the corresponding pointer conversion is allowed.

Arithmetic conversions and promotions Integral conversions Boolean conversion Floating point conversion Integral and floating

Arithmetic conversions and promotions Integral conversions Boolean conversion Floating point conversion Integral and floating point promotions

Pointer Conversion Qualification conversions An type-qualified rvalue of any type, containing zero or more

Pointer Conversion Qualification conversions An type-qualified rvalue of any type, containing zero or more const or volatile qualifications, can be converted to an rvalue of typequalified type where the second rvalue contains more const or volatile qualifications than the first rvalue. An rvalue of type pointer to member of a class can be converted to an rvalue of type pointer to member of a class if the second rvalue contains more const or volatile qualifications than the first rvalue.

Cont… Function argument conversions When a function is called, if a function declaration is

Cont… Function argument conversions When a function is called, if a function declaration is present and includes declared argument types, the compiler performs type checking. The compiler compares the data types provided by the calling function with the data types that the called function expects and performs necessary type conversions. For example, when function funct is called, argument f is converted to a double, and argument c is converted to an int: The automatic conversions consist of the following: 1. Integral and floating-point values are promoted. 2. Arrays or functions are converted to pointers. 3. Non-static class member functions are converted to pointers to members.

Cont… char * funct (double d, int i); /*. . . */ int main(void)

Cont… char * funct (double d, int i); /*. . . */ int main(void) { float f; char c; funct(f, c) /* f is converted to a double, c is converted to an int */ return 0; }

Explicit initialization with constructors A class object with a constructor must be explicitly initialized

Explicit initialization with constructors A class object with a constructor must be explicitly initialized or have a default constructor. Except for aggregate initialization, explicit initialization using a constructor is the only way to initialize nonstatic constant and reference class members. A class object that has no constructors, no virtual functions, no private or protected members, and no base classes is called an aggregate. Examples of aggregates are C-style structures and unions. You explicitly initialize a class object when you create that object. There are two ways to initialize a class object: Using a parenthesized expression list. The compiler calls the constructor of the class using this list as the constructor's argument list. Using a single initialization value and the = operator. Because this type of expression is an initialization, not an assignment, the assignment operator function, if one exists, is not called. The type of the single argument must match the type of the first argument to the constructor. If the constructor has remaining arguments, these arguments must have default values.

example illustrates explicit initialization #include <iostream> using namespace std; class complx { double re,

example illustrates explicit initialization #include <iostream> using namespace std; class complx { double re, im; public: complx() : re(0), im(0) { } // default constructor // copy constructor complx(const complx& c) { re = c. re; im = c. im; } // constructor with default trailing argument complx( double r, double i = 0. 0) { re = r; im = i; } void display() { cout << "re = "<< re << " im = " << im << endl; } };

Cont… int main() { // initialize with complx(double, double) complx one(1); // initialize with

Cont… int main() { // initialize with complx(double, double) complx one(1); // initialize with a copy of one // using complx: : complx(const complx&) complx two = one; // construct complx(3, 4) // directly into three complx three = complx(3, 4); // initialize with default constructor complx four; // complx(double, double) and construct // directly into five complx five = 5; one. display(); two. display(); three. display(); four. display(); five. display(); }