Presentation is loading. Please wait.

Presentation is loading. Please wait.

Introduction to Classes in C++

Similar presentations


Presentation on theme: "Introduction to Classes in C++"— Presentation transcript:

1 Introduction to Classes in C++

2 Object Oriented Paradigm
Class Attribute Method Message Encapsulation Inheritance Polymorphism Abstract Data Type: from struct to class

3 Classes in C++ class Myclass // class head
{ // indicates beginning of class body public: // public data and functions type myfunc( ); protected: // protected data and functions private: // private data and functions type myvar; }; // indicates end of class body

4 Levels of Data Access Information hiding is a formal mechanism for restricting user access to the internal representation of a class type Members are declared as public protected private

5 Member Functions Any function that is declared as part of a class is called a member function Member functions are invoked by sending messages to an instance of the class The . (dot) operator is the “message send” operator: instance.function(parameters) Member functions within the same class can call each other without using the . (dot) operator

6 Rational Number Class class Rational // implement rational numbers with addition { // the only operation defined public: void initialize(int num, int den); void print ( ); Rational add(Rational r); private: int numerator; int denominator; int gcd(int i, int j); void commonDenominator(Rational& r); };

7 Review of .h and .C Class declarations typically are placed in a dot h (.h file). Member function definitions typically are placed in a .C file. The .C file requires an “include” statement: #include “Class_name.h”

8 Scope Resolution Operator
:: is used to define the code for a member function outside of its class declaration. It can also be used to reference global variables even when the same name has been used for a local. For example, int a = 15; int f( ) { int a = 100; cout << ::a; } will print the value 15.

9 Rational Number Class #include “Rational.h”
void Rational::initialize(int numerator, int denominator) { // initialize the numerator and denominator members this->numerator = numerator; this->denominator = denominator; }

10 Rational Number Class (Continued)
#include “Rational.h” #include <math.h> int Rational::gcd(int i, int j) { // Find greatest common divisor of 2 integers int divisor; i = abs(i); j = abs(j); for (divisor = (i<j) ? i : j; divisor > 1 && (i % divisor != 0 || j % divisor != 0); divisor--); return divisor; }

11 Rational Number Class (Continued)
void Rational::commonDenominator(Rational& r) { // given two rational numbers, convert them // to have a common denominator int multiplier1, multiplier2; int divisor = gcd(denominator, r.denominator); multiplier1 = denominator / divisor; multiplier2 = r.denominator/divisor; numerator *= multiplier2; denominator *= multiplier2; r.numerator *= multiplier1; r.denominator *= multiplier1; }

12 Rational Number Class (Continued)
Rational Rational::add(Rational r) { Rational temp = *this; Rational i; temp.commonDenominator(r); i.initialize(temp.numerator + r.numerator, temp.denominator); return i; } void Rational::print( ) cout << numerator << “/” << denomiator;

13 Using the Rational Number Class
Rational a, b, c; a.initialize(1, 2); b.initialize(2, 3); c.initialize(1, 1); a.print( ); b.print( ); c = a.add(b); // Can’t do: // print(); a.print( ); // a.commonDenominator(b); b.print( ); // cout << a.denominator; c.print( );

14 Notes About Class Definitions
Classes and structs are equivalent, except that all members are private by default in a class, and public by default in a struct. The keyword, this, references a pointer to the receiver of a message. Data items in the receiver can be referenced directly by using the instance variable name. Member functions can access the private data of an instance of the class. In other words, only member functions can “reference and dereference” private class instance variables.

15 Some Common Errors Leaving off the semicolon after the class declaration gives the following errors (among others): bad base type: class int class Rational defined as return type for gcd() (did you forget a ‘:’ after ‘}’ ?) class Rational undefined Leaving off the Rational::, in front of the definition of gcd gives the following error at link time: Undefined entry, name: (Error 28) “gcd__8RationalFiT1”

16 Constructors and Destructors

17 Rational Number Class class Rational // implement rational numbers with addition { // the only operation defined public: void initialize(int num, int den); void print ( ); Rational add(Rational r); private: int numerator; int denominator; int gcd(int i, int j); void commonDenominator(Rational& r); };

18 Constructor Syntax Class Myclass { Public:
Myclass( ); // void constructor Myclass(int n); // one-parameter constructor }; #include “Myclass.h” Void main( ) Myclass i; // invokes void constructor Myclass j(3); // invokes the one-parameter constructor }

19 Constructor A member function with the same name as the class is called a constructor. Constructors are called whenever a member of the class is created (declarations, parameter passing, function returns). Constructor declarations can appear only inside of class declarations. Any number of constructors are allowed. Constructors cannot have return types.

20 Rational Number Class with Constructors-1
class Rational // implement rational numbers with addition { // the only operation defined public: Rational( ); // void constructor Rational(int n); // one-parameter constructor Rational(int n, int d); // two-parameter constructor void print ( ); Rational add(Rational r); private: int numerator; int denominator; int gcd(int i, int j); void commonDenominator(Rational& r); };

21 Rational Number Class with Constructors-2
class Rational // implement rational numbers with addition { // the only operation defined public: Rational(){ numerator = 0; denominator = 1; } Rational(int n){ numerator = n; Rational(int n, int d){ numrator = n; denominator = d;

22 Rational Number Class with Constructors-3
The original add function Rational Rational::add(Rational r) { Rational temp = *this; Rational i; temp.commonDenominator(r); i.initialize(temp.numerator + r.numerator, temp.denominator); return i; } The new add function using constructors return Rational(temp.numerator + r.numerator, temp.denominator);

23 Default Constructor Arguments
With default arguments and a single constructor, it is possible to declare: Rational a, b(3), c(1,4) calss Rational { Rational (int num=0, int den=1) if(den < 0){ num = -num; den = -den; } numerator = num; denominator = den; };

24 Inline Code Inline causes the actual code for a function to be substituted for a call to the function. Member functions can be made inline by putting their definition (that is, their code) within the class declaration or by preceding their definition, outside of the class, by the keyword inline. Any other function is made inline by preceding its definition with the keyword inline. Inline is a suggestion to the translator. For example, functions containing loops will not be made inline.

25 Inline Code (Continued)
calss Rational // With in-line constructor { Rational (int num=0, int den=1) if(den < 0){ num = -num; den = -den; } numerator = num; denominator = den; };

26 Inline Code (Continued)
An alternative inline Rational::Rational (int num=0, int den=1) { if(den < 0){ num = -num; den = -den; } numerator = num; denominator = den;

27 Vectors of Class Instances
A class must have a constructor with no arguments (a void constructor), in order to declare a vector of instances of it, without explicitly initializing the entire vector. A constructor with all of its arguments having default values is equivalent to a void constructor. Arrays of class instances can be initialized using any combination of constructors. There must be enough initializers for the entire vector.

28 Vectors of Class Instances (Continued)
main() { Rational fractions1[25]; Rational fractions2[3]={Rational(1,2), Rational( ), 4}; fractions1[0] = Rational(1,4); fractions2[1] = Rational(1,2); fractions2[1].print( ); }

29 Destructor A destructor is a function named by ~className.
A destructor is invoked whenever an element of the class is destroyed (leaving scope, dynamic freeing, deallocation of temporary) Destructor declarations can appear only inside of class declarations. There can be, at most, one destructor. Destructors cannot have parameters or return types.

30 Destructor (Continued)
class Rational // With Destructor { public: ~Rational( ) cout << “Instance of Rational destroyed” << endl; } };

31 Some Common Errors If you have provided one or more constructors, but not a void constructor, the following errors are possible: The declaration Rational r[25]; causes the following error message: array of class Rational that does not have a constructor taking no arguments The declaration Rational r; gives the following error message: argument 1 of type int expected for Rational::Rational( )

32 Static Members Members declared to be static are shared among all instances of a class If a static member is public, it can be referred to outside of the class: className::staticMember; Static members cannot be initialized when declared. Therefore, if they are instances of a class, the class must have a void constructor, if it has any constructors. A static member, whether private or public, must be initialized, exactly once, at file scope: type className::staticMember = initialValue;

33 Static Members (Continued)
class Rational { public: int howMany( ); private: static int numRationals; };

34 Static Members (Continued)
In each constructor, add the following statement: numRationals++; In the destructor, add the follwing statement: numRational--; Initialize the static somewhere at file scope: int Rational::numRationals = 0; Implement the howMany( ) function: int Rational::howMany( ) { return numRationals; }

35 Static Member Functions
Member functions accessing only static members can be declared static. Static member functions can be called though a member or by ClassName::ftn( ). For example, Rational::howMany( ) Static member functions have no this pointer. Any explicit reference to this, or to a nonstatic member, causes a compile-time error.

36 Static Member Functions
class Rational { public: static int howMany( ); // Return the number of Rationals at any time private: static int numRationals; };

37 Overloading Functions

38 Overloading Functions
The following are allowed in the same program: int f(int a); float f(float a); int f(int a, int b); int f(int a, float b); int f(char a); int f(int a, int b, int c, …)

39 Overloading Functions (Continued)
Given the declarations on the previous slide, the function declaration float f(int a) generates the error message two different return value types for f( ): int and float int f(int a, int b, int c=1); two exact matches for f( ): int (int, int, int) and int (int, int)

40 Overloading Functions (Continued)
Overloaded functions must be distinguishable by the number and type of arguments. Return type cannot be used to distinguish overloaded functions. The number, type, and order of the arguments establishes the function signature

41 Default Arguments When default arguments are used, the resulting function is equivalent to a set of functions whose members are that function with each possible number of arguments. For example, the function declaration void f (int a = 1, int b = 2, int c = 3); is equivalent to the four declarations void f( ); void f(int); void f(int, int); void f(int, int, int);

42 Argument Matching Each argument in a call to an overloaded function is compared to the corresponding arguments in the declaration. The compiler will choose the function for which each argument resolution is the same or better than for the other functions. If there is either no match or an ambiguous match, a compilation error is generated. The argument matching algorithm distinguishes between constant and nonconstant pointer and reference arguments.

43 Argument Matching (Continued)
The comparison takes place using following steps: Look for an exact match Look for a match using promotions Look for a match based on standard conversions (for example, SomeClass* to void*) Look for a match using user-defined conversions. Only one level of user-defined conversion will be used

44 Argument Matching Given the declarations void f (int, float);
void f(float, int); the call f(1.5, 1.5); Gives the error message two standard conversions possible for f(): void (int, float) and void (float, int)

45 Constant Member Functions
A member function can be declared as constant by adding the keyword const between the argument list and the body of the function. Only constant member functions can be sent to class instances declared as constant. It is illegal to declare a member function as constant if it modifies an instance variable. There can be constant and nonconstant version of a member function. The function is selected, based on whether or not the receiver is a constant.

46 Constant Member Functions
class Rational { void print( ) const; }; void Rational::print( ) const } main() const Rational r(3,5); r.print();

47 Overloading Operators

48 Rational Number Class Rational Rational::add(Rational r) {
Rational temp = *this; temp.commonDenominator(r); return Rational(temp.numerator + r.numerator, temp.denominator); }

49 Overloading an Operator
Operator overloading is redefining and operator that has a built-in function. The function name consists of the keyword operator, followed by the operator symbol For example, given a String class, we can write the following function to concatenate two Strings: String operator+ (String x); The we can concatenate the Strings: String a, b, c; a = b + c;

50 Overloading Operators
class Rational { public: Rational operator+ (Rational); protected: private: int numerator; int denominator; int gcd(int i, int j); void commonDenominator(Rational& r); };

51 Overloading Operators (Continued)
Rational Rational::operator + (Rational r) { Rational temp = *this; temp.commonDenominator(r); return Rational(temp.numerator+r.numerator, temp.denominator); } Using + operator: Rational a(1,4), b(1,3), c(1,1); c = a + b; // c = a.operator+(b);

52 Overloading Operators (Continued)
Functions can be named with standard C++ operators. The types of the operands are used to distinguish between the various declarations The operator does not imply any particular semantics. Precedence follows standard C++ precedence rules. It is possible to overload the prefix and postfix increment (++) and decrement (--) operators.

53 Overloading Operators (Continued)
op1 binaryOp op2 is interpreted as op1 receiving the message binaryOp with the argument op2. The expression can also be written as follows: op1. oprator binaryOp(op2) For example r1 + r2 or r1.operator+(r2)

54 Friends Classes or functions can be declared to be a friend of a class. Friends have access to the private members of a class. Friend functions are not received by class instances and thus do not have access to this pointer. Friend functions are necessary when the left operand is not an instance of the class being defined.

55 Friends versus Members
class Rational { public: friend Rational operator+(Rational, Rational); } Versus the member function Rational operator+(Rational); };

56 Friends versus Members (Continued)
Binary operators that are friend functions have two arguments; those that are member functions have one. Unary operators that are friend functions have one argument; those that are member functions have none. Constructors, destructors, and virtual functions must be members. The overloaded operators = (assignment), ( ) (function call), [ ] (subscripting), and -> (class member access) must be member functions, not friends. Operations modifying state should be members. Choose members when possible.

57 A Special Friend class Rational {
friend ostream& operator << (ostream&, Rational&); … }; ostream& operator << (ostream& s, Rational& r) return (s << r.numerator << “/” << r.denominator << “\n”); }

58 Constructors for Type Conversion
class Rational { public: Rational operator+(Rational); Rational operator+(int); friend Rational operator+(int, Rational); };

59 Constructors for Type Conversion (Continued)
Using implicit type conversion is easier: class Rational { public: Rational (int, int=1); // or any constructor that takes one int friend Rational operator+(Rational, Rational); };

60 Constructors for Type Conversion (Continued)
Both of these allow: Rational a(1, 2), b(1, 1); b = a + a; b = a + 1; b = 1 + a; Using implicit conversion allows the addtion function to be written once instead of three times.

61 Constructors for Type Conversion (Continued)
A constructor with one argument is a user-defined conversion operator that can be implicitly applied Only one level of conversion will be implicitly applied. Conversion can be explicitly requested by casting: typeName(expression) This notation can also be used for basic types as an alternative to the traditional C cast notation. Member functions are invoked only for real objects; friend functions can be called for an object created by implicit conversion.

62 Conversion Operators class Rational { … public:
operatior int( ) //convert from Rational to int return int (float (numerator) / denominator + 0.5); }

63 Constructors for Type Conversion
There are several limitations in using constructors for type conversion: They may not allow implicit conversion from a user-defined type to a basic type They must modify the declaration for an old type when specifying a conversion from a new type to it. When both forms of type conversion are in a program, the compiler flags ambiguities. For example, if both the one-parameter constructor for Rational and the int( ) operator exist, given Rational a(1, 2); a + 1 generates a compile-time error, because a can be converted to an int, or 1 can be converted to a Rational.


Download ppt "Introduction to Classes in C++"

Similar presentations


Ads by Google