Chapter 21 - Standard C++ Language Additions

42
2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved. Chapter 21 - Standard C++ Language Additions Outline 21.1 Introduction 21.2 bool Data Type 21.3 static_cast Operator 21.4 const_cast Operator 21.5 reinterpret_cast Operator 21.6 namespaces 21.7 Run-Time Type Information (RTTI) 21.8 Operator Keywords 21.9 explicit Constructors 21.10 mutable Class Members 21.11 Pointers to Class Members (.* and ->*) 21.12 Multiple Inheritance and virtual Base Classes

description

Chapter 21 - Standard C++ Language Additions. Outline 21.1Introduction 21.2 bool Data Type 21.3 static_cast Operator 21.4 const_cast Operator 21.5 reinterpret_cast Operator 21.6namespaces 21.7Run-Time Type Information (RTTI) 21.8Operator Keywords - PowerPoint PPT Presentation

Transcript of Chapter 21 - Standard C++ Language Additions

Page 1: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Chapter 21 - Standard C++ Language Additions

Outline21.1 Introduction21.2 bool Data Type21.3 static_cast Operator21.4 const_cast Operator21.5 reinterpret_cast Operator21.6 namespaces21.7 Run-Time Type Information (RTTI)21.8 Operator Keywords21.9 explicit Constructors21.10 mutable Class Members21.11 Pointers to Class Members (.* and ->*)21.12 Multiple Inheritance and virtual Base Classes

Page 2: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

21.1Introduction

• We shall cover standard C++ features – data type bool – cast operators – namespaces – run-time type information (RTTI) – operator keywords

Page 3: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

21.2bool Data Type

•bool - can be false or true – preferable to 0 (false) and non-zero (true)

• outputting bool variables– numerical default (0 or 1)– stream manipulator boolalpha

• outputs string "true" or "false"

Examples:cout << boolVariable

cout << boolalpha << boolVariable

Page 4: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Outline

1. Initialize bool variable an int.

2. Input a variable.

3. Print the bool value of the int.

3.1 Print the value of bool variable.

1 // Fig. 21.1: fig21_01.cpp

2 // Demonstrating data type bool.

3 #include <iostream>

4

5 using std::cout;

6 using std::endl;

7 using std::cin;

8 using std::boolalpha;

9

10 int main()

11 {

12 bool boolean = false;

13 int x = 0;

14

15 cout << "boolean is " << boolean

16 << "\nEnter an integer: ";

17 cin >> x;

18

19 cout << "integer " << x << " is"

20 << ( x ? " nonzero " : " zero " )

21 << "and interpreted as ";

22

boolean is 0

Enter an integer: 22

Page 5: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Outline

3.2 Print the string value of the bool variable.

Program Output

23 if ( x )24 cout << "true\n";25 else26 cout << "false\n";2728 boolean = true;29 cout << "boolean is " << boolean;30 cout << "\nboolean output with boolalpha manipulator is " 31 << boolalpha << boolean << endl;3233 return 0;34 }

boolean is 0Enter an integer: 22integer 22 is nonzero and interpreted as trueboolean is 1boolean output with boolalpha manipulator is true

Notice how the output varies.

boolean is 1

boolean output with boolalpha manipulator is true

integer 22 is nonzero and interpreted as true

Page 6: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

21.3static_cast Operator

• C++ has 4 separate, specific casts

• static_cast - conversion between types– type checking at compile time

– standard conversions: void* to char*, int to float, etc.

– base class pointers to derived class pointers

• Format:static_cast<type to convert to>(object to convert)

int z = 3;

float x = static_cast<int>(z);

Page 7: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Outline

1. Define class BaseClass

1.1 Define member function

1.2 Define class DerivedClass

1.3 Define member function

1.4 Global function prototype(calls function f)

2. Function calls

3. Output results

1 // Fig. 21.2: fig21_02.cpp

2 // Demonstrating the static_cast operator.

3 #include <iostream>

4

5 using std::cout;

6 using std::endl;

7

8 class BaseClass {

9 public:

10 void f( void ) const { cout << "BASE\n"; }

11 };

12

13 class DerivedClass : public BaseClass {

14 public:

15 void f( void ) const { cout << "DERIVED\n"; }

16 };

17

18 void test( BaseClass * );

19

20 int main()

21 {

22 // use static_cast for a conversion

23 double d = 8.22;

24 int x = static_cast< int >( d );

25

26 cout << "d is " << d << "\nx is " << x << endl;

27

28 BaseClass * basePtr = new DerivedClass;

29 test( basePtr ); // call test

30 delete basePtr;

convert double to int

d is 8.22x is 8

Page 8: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Outline

3.1 Function definition

Program Output

31

32 return 0;

33 }

34

35 void test( BaseClass * basePtr )

36 {

37 DerivedClass *derivedPtr;

38

39 // cast base class pointer into derived class pointer

40 derivedPtr = static_cast< DerivedClass * >( basePtr );

41 derivedPtr->f(); // invoke DerivedClass function f

42 }

d is 8.22x is 8DERIVED

converts a base pointer to a derived pointer, and calls the derived function f

Page 9: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Outline

1. Class definition

1.1 Initialize objects

2. Print

1 // Fig. 21.2: fig21_02.cpp

2 // Demonstrating the static_cast operator.

3 #include <iostream>

4

5 using std::cout;

6 using std::endl;

7

8 class BaseClass {

9 public:

10 void f( void ) const { cout << "BASE\n"; }

11 };

12

13 class DerivedClass : public BaseClass {

14 public:

15 void f( void ) const { cout << "DERIVED\n"; }

16 };

17

18 void test( BaseClass * );

19

20 int main()

21 {

22 // use static_cast for a conversion

23 double d = 8.22;

24 int x = static_cast< int >( d );

25

26 cout << "d is " << d << "\nx is " << x << endl;

27

28 BaseClass * basePtr = new DerivedClass;

29 test( basePtr ); // call test

30 delete basePtr;

In const function print the this pointer is originally const ConstCastTest *. It is cast into type ConstCastTest *, and can then be modified.

Page 10: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Outline

3. Function definition

Program Output

31

32 return 0;

33 }

34

35 void test( BaseClass * basePtr )

36 {

37 DerivedClass *derivedPtr;

38

39 // cast base class pointer into derived class pointer

40 derivedPtr = static_cast< DerivedClass * >( basePtr );

41 derivedPtr->f(); // invoke DerivedClass function f

42 }

d is 8.22x is 8DERIVED

Page 11: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

21.4const_cast Operator

• const_cast - cast away const or volatile – cannot be used directly to cast away const-ness

• use pointers

Page 12: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Outline

1. Define class ConstCastTest

1.1 Define member functions

1 // Fig. 21.3: fig21_03.cpp

2 // Demonstrating the const_cast operator.

3 #include <iostream>

4

5 using std::cout;

6 using std::endl;

7

8 class ConstCastTest {

9 public:

10 void setNumber( int );

11 int getNumber() const;

12 void printNumber() const;

13 private:

14 int number;

15 };

16

17 void ConstCastTest::setNumber( int num ) { number = num; }

18

19 int ConstCastTest::getNumber() const { return number; }

20

21 void ConstCastTest::printNumber() const

22 {

23 cout << "\nNumber after modification: ";

24

25 // the expression number-- would generate compile error

Page 13: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Outline

2. Create and initialize object

3. Modify and print object with a const function.

Program Output

26 // undo const-ness to allow modification27 const_cast< ConstCastTest * >( this )->number--;2829 cout << number << endl;30 }3132 int main()33 {34 ConstCastTest x;35 x.setNumber( 8 ); // set private data number to 836 37 cout << "Initial value of number: " << x.getNumber();3839 x.printNumber();40 return 0;41 }

Initial value of number: 8Number after modification: 7

Casts the this pointer into type ConstCastTest *. This casts away the "const-ness" and allows number to be modified.

Page 14: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

21.5reinterpret_cast Operator

• reinterpret_cast - for nonstandard casts – one pointer type to another pointer type, void* to int, etc.

– cannot be used for standard casts (int to double, etc.).

Page 15: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Outline

1. Initialize variables and pointers

2. Cast a pointer to pointer of a different type

3. Output data

Program Output

1 // Fig. 21.4: fig21_04.cpp

2 // Demonstrating the reinterpret_cast operator.

3 #include <iostream>

4

5 using std::cout;

6 using std::endl;

7

8 int main()

9 {

10 int x = 120, *ptr = &x;

11

12 cout << *reinterpret_cast<char *>( ptr ) << endl;

13

14 return 0;

15 }

x

ptr (type int *) cast to a pointer of type (char *).

120 is the ASCII character code for 'x'

Page 16: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

21.6namespaces

• variables with same name and different scopes can overlap– need to distinguish them

• a namespace defines a scope for local and global identifiers.– body delimited by braces {}– use (::) to access namespace members:

namespace_name::member

– or, a using statement must occur before name is usedusing namespace namespace_name;

-members of the namespace do not need a prefix

– not guaranteed to be unique

– can be nested

Page 17: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

21.6namespaces (II)

• Unnamed namespaces– occupy global namespace– directly accessible– do not need namespace name– global variables are in global namespace

• accessible in all scopes

Page 18: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Outline

1. Use std namespace

1.1 Declare global variable

1.2 Define namespace Example

1.3 Define namespace inner

1.4 Define unnamed namespace

2. Print variables

1 // Fig. 21.5: fig21_05.cpp

2 // Demonstrating namespaces.

3 #include <iostream>

4 using namespace std; // use std namespace

5

6 int myInt = 98; // global variable

7

8 namespace Example {

9 const double PI = 3.14159;

10 const double E = 2.71828;

11 int myInt = 8;

12 void printValues();

13

14 namespace Inner { // nested namespace

15 enum Years { FISCAL1 = 1990, FISCAL2, FISCAL3 };

16 }

17 }

18

19 namespace { // unnamed namespace

20 double d = 88.22;

21 }

22

23 int main()

24 {

25 // output value d of unnamed namespace

26 cout << "d = " << d;

27

28 // output global variable

29 cout << "\n(global) myInt = " << myInt;

Unnamed namespace members do not need qualifiers

d = 88.22

(global) myInt = 98

Page 19: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Outline

2. Print variables

3. Function definition

31 // output values of Example namespace

32 cout << "\nPI = " << Example::PI << "\nE = "

33 << Example::E << "\nmyInt = "

34 << Example::myInt << "\nFISCAL3 = "

35 << Example::Inner::FISCAL3 << endl;

36

37 Example::printValues(); // invoke printValues function

38

39 return 0;

40 }

41

42 void Example::printValues()

43 {

44 cout << "\nIn printValues:\n" << "myInt = "

45 << myInt << "\nPI = " << PI << "\nE = "

46 << E << "\nd = " << d << "\n(global) myInt = "

47 << ::myInt << "\nFISCAL3 = "

48 << Inner::FISCAL3 << endl;

49 }

PI = 3.14159

E = 2.71828

myInt = 8

FISCAL3 = 1992

In printValues:

myInt = 8

PI = 3.14159

E = 2.71828

d = 88.22

(global) myInt = 98

FISCAL3 = 1992

Function printValues is a member of Example and does not need a namespace qualifier.

Page 20: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Outline

Program Output

d = 88.22(global) myInt = 98PI = 3.14159E = 2.71828myInt = 8FISCAL3 = 1992 In printValues:myInt = 8PI = 3.14159E = 2.71828d = 88.22(global) myInt = 98FISCAL3 = 1992

Page 21: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

21.7Run-Time Type Information (RTTI)

• determines an object's type at run time

• typeid (in <typeinfo>)typeid(object).name()

- returns the name of the object as a C-style string

• dynamic_cast - for polymorphic programming– often used to downcast base-class pointer to derived-class pointer

– used with virtual functions

Page 22: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Outline

1. Define base and derived classes

1 // Fig. 21.7: fig21_07.cpp2 // Demonstrating dynamic_cast.3 #include <iostream>45 using std::cout;6 using std::endl;78 const double PI = 3.14159;910 class Shape {11 public:12 virtual double area() const { return 0.0; }13 };1415 class Circle : public Shape {16 public:17 Circle( int r = 1 ) { radius = r; }1819 virtual double area() const 20 { 21 return PI * radius * radius; 22 };23 protected:24 int radius;25 };2627 class Cylinder : public Circle {28 public:29 Cylinder( int h = 1 ) { height = h; }3031 virtual double area() const 32 { 33 return 2 * PI * radius * height +

Page 23: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Outline

1.1 Function prototype

1.2 Declare objects

2. Function calls

3. Define function.

34 2 * Circle::area();35 }36 private:37 int height;38 };3940 void outputShapeArea( const Shape * ); // prototype4142 int main()43 {44 Circle circle;45 Cylinder cylinder;46 Shape *ptr = 0;4748 outputShapeArea( &circle ); // output circle's area49 outputShapeArea( &cylinder ); // output cylinder's area50 outputShapeArea( ptr ); // attempt to output area51 return 0;52 }5354 void outputShapeArea( const Shape *shapePtr )55 {56 const Circle *circlePtr;57 const Cylinder *cylinderPtr;5859 // cast Shape * to a Cylinder *60 cylinderPtr = dynamic_cast< const Cylinder * >( shapePtr );6162 if ( cylinderPtr != 0 ) // if true, invoke area()63 cout << "Cylinder's area: " << shapePtr->area(); 64 else { // shapePtr does not refer to a cylinder65 66 // cast shapePtr to a Circle *

Notice how shapePtr is cast to various types. If it is not of the right type, the cast returns 0.

Page 24: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Outline

3. Define function.

Program Output

67 circlePtr = dynamic_cast< const Circle * >( shapePtr );

68

69 if ( circlePtr != 0 ) // if true, invoke area()

70 cout << "Circle's area: " << circlePtr->area();

71 else

72 cout << "Neither a Circle nor a Cylinder.";

73 }

74

75 cout << endl;

76 }

Circle's area: 3.14159Cylinder's area: 12.5664Neither a Circle nor a Cylinder.

Notice how shapePtr is cast to various types. If it is not of the right type, the cast returns 0.

Page 25: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

21.8Operator Keywords

• can use keywords in place of operators (such as !, &, ^, etc.). – use header <iso646.h> (may vary with compiler)

Operator Keyword Description

Logical operator keywords

&& and logical AND

|| or logical OR

! not logical NOT

Inequality operator keyword

!= not_eq inequality

Bitwise operator keywords

& bitand bitwise AND

| bitor bitwise inclusive OR

^ xor bitwise exclusive OR

~ compl bitwise complement

Bitwise assignment operator keywords

&= and_eq bitwise AND assignment

|= or_eq bitwise inclusive OR assignment

^= xor_eq bitwise exclusive OR assignment

Page 26: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Outline

1. Load header

1.1 Initialize variables

2. Use operator keywords

3. Print results

1 // Fig. 21.9: fig21_09.cpp

2 // Demonstrating operator keywords.

3 #include <iostream>

4

5 using std::cout;

6 using std::endl;

7 using std::boolalpha;

8

9 #include <iso646.h>

10

11 int main()

12 {

13 int a = 8, b = 22;

14

15 cout << boolalpha

16 << " a and b: " << ( a and b )

17 << "\n a or b: " << ( a or b )

18 << "\n not a: " << ( not a )

19 << "\na not_eq b: " << ( a not_eq b )

20 << "\na bitand b: " << ( a bitand b )

21 << "\na bit_or b: " << ( a bitor b )

22 << "\n a xor b: " << ( a xor b )

23 << "\n compl a: " << ( compl a )

24 << "\na and_eq b: " << ( a and_eq b )

25 << "\n a or_eq b: " << ( a or_eq b )

26 << "\na xor_eq b: " << ( a xor_eq b ) << endl;

27

28 return 0;

29 }

Operator keywords can be used instead of the symbols

Page 27: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Outline

Program Output

a and b: true a or b: true not a: falsea not_eq b: falsea bitand b: 22a bit_or b: 22 a xor b: 0 compl a: -23a and_eq b: 22 a or_eq b: 30a xor_eq b: 30

Page 28: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

21.9explicit Constructors

• constructors with one argument can be used for implicit conversion– type received by constructor turned into an object

– automatic conversion sometimes undesirable

• keyword explicit prevents implicit conversion– use before constructor prototype in class definition

Page 29: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Outline

1. Define Array class

1.1 Define constructor

1.2 Define destructor

2. Create object

2.1 Print Array object

2.2 Print int

3. Function definition

1 // Fig. 21.9: fig21_09.cpp

2 // Demonstrating operator keywords.

3 #include <iostream>

4

5 using std::cout;

6 using std::endl;

7 using std::boolalpha;

8

9 #include <iso646.h>

10

11 int main()

12 {

13 int a = 8, b = 22;

14

15 cout << boolalpha

16 << " a and b: " << ( a and b )

17 << "\n a or b: " << ( a or b )

18 << "\n not a: " << ( not a )

19 << "\na not_eq b: " << ( a not_eq b )

20 << "\na bitand b: " << ( a bitand b )

21 << "\na bit_or b: " << ( a bitor b )

22 << "\n a xor b: " << ( a xor b )

23 << "\n compl a: " << ( compl a )

24 << "\na and_eq b: " << ( a and_eq b )

25 << "\n a or_eq b: " << ( a or_eq b )

26 << "\na xor_eq b: " << ( a xor_eq b ) << endl;

27

28 return 0;

29 }

15 is not an Array object, but it is implicitly converted to an Array object using the conversion constructor. This new object is printed using outputArray.

If the keyword explicit comes before the constructor, this program will issue a compiler error - outputArray cannot take an int.

Page 30: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Outline

Program Output

a and b: true a or b: true not a: falsea not_eq b: falsea bitand b: 22a bit_or b: 22 a xor b: 0 compl a: -23a and_eq b: 22 a or_eq b: 30a xor_eq b: 30

Page 31: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Outline

1. Class definition

1.1 Function prototype

1.2 Member variables

----------------------

1. Load header file

1 // Fig 21.10: array2.h

2 // Simple class Array (for integers)

3 #ifndef ARRAY2_H

4 #define ARRAY2_H

5

6 #include <iostream>

7

8 using std::ostream;

9

10 class Array {

11 friend ostream &operator<<( ostream &, const Array & );

12 public:

13 Array( int = 10 ); // default/conversion constructor

14 ~Array(); // destructor

15 private:

16 int size; // size of the array

17 int *ptr; // pointer to first element of array

18 };

19

20 #endif

21 // Fig 21.10: array2.cpp22 // Member function definitions for class Array23 #include <iostream>2425 using std::cout;26 using std::ostream;2728 #include <cassert>29 #include "array2.h"30

Page 32: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Outline

1.1 Function definitions

31 // Default constructor for class Array (default size 10)

32 Array::Array( int arraySize )

33 {

34 size = ( arraySize > 0 ? arraySize : 10 );

35 cout << "Array constructor called for "

36 << size << " elements\n";

37

38 ptr = new int[ size ]; // create space for array

39 assert( ptr != 0 ); // terminate if memory not allocated

40

41 for ( int i = 0; i < size; i++ )

42 ptr[ i ] = 0; // initialize array

43 }

44

45 // Destructor for class Array

46 Array::~Array() { delete [] ptr; }

47

48 // Overloaded output operator for class Array

49 ostream &operator<<( ostream &output, const Array &a )

50 {

51 int i;

52

53 for ( i = 0; i < a.size; i++ )

54 output << a.ptr[ i ] << ' ' ;

55

56 return output; // enables cout << x << y;

57 }

Page 33: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Outline

1. Load header

1.1 Initialize object

2. Print object

3. Function definition

58 // Fig 21.10: fig21_10.cpp

59 // Driver for simple class Array

60 #include <iostream>

61

62 using std::cout;

63

64 #include "array2.h"

65

66 void outputArray( const Array & );

67

68 int main()

69 {

70 Array integers1( 7 );

71

72 outputArray( integers1 ); // output Array integers1

73

74 outputArray( 15 ); // convert 15 to an Array and output

75

76 return 0;

77 }

78

79 void outputArray( const Array &arrayToOutput )

80 {

81 cout << "The array received contains:\n"

82 << arrayToOutput << "\n\n";

83 }

outputArray needs a parameter of type const Array &, so 15 is converted into an Array by the conversion constructor.

Page 34: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Outline

Program Output

Array constructor called for 7 elementsThe array received contains:0 0 0 0 0 0 0 Array constructor called for 15 elementsThe array received contains:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Page 35: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

21.10 mutable Class Members

• mutable data member– always modifiable, even in a const function or object

– permanently allows a const data member to be modified

• const_cast: – used every time a const data member must be

modified

– reduces risk of accidentally modifying a const variable

Page 36: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

21.11 Pointers to Class Members (.* and ->*)

• pointers to class members are different from normal pointers

• use .* and ->* instead of . and -> when accessing class members (functions and data)

Page 37: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Outline

1. Class definition

1.1 Function prototypes

1.2 Initialize object

2. Function calls

1 // Fig. 21.13 fig21_13.cpp

2 // Demonstrating operators .* and ->*

3 #include <iostream>

4

5 using std::cout;

6 using std::endl;

7

8 class Test {

9 public:

10 void function() { cout << "function\n"; }

11 int value;

12 };

13

14 void arrowStar( Test * );

15 void dotStar( Test * );

16

17 int main()

18 {

19 Test t;

20

21 t.value = 8;

22 arrowStar( &t );

23 dotStar( &t );

24 return 0;

25 }

Page 38: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Outline

3. Function definitions

Program Output

26

27 void arrowStar( Test *tPtr )

28 {

29 void ( Test::*memPtr )() = &Test::function;

30 ( tPtr->*memPtr )(); // invoke function indirectly

31 }

32

33 void dotStar( Test *tPtr )

34 {

35 int Test::*vPtr = &Test::value;

36 cout << ( *tPtr ).*vPtr << endl; // access value

37 }

function8

arrowStar declares and initializes memPtr to point to a function in Test that takes no parameters and returns no value.

&Test::function to get the offset into the class for member function function.

Without Test::, memPtr is a standard pointer.

dotStar declares and initializes vPtr to point to value.

The .* operator is then used to access the member to which vPtr points.

Page 39: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

21.12 Multiple Inheritance and virtual Base Classes

• Ambiguities can result with multiple inheritance

• iostream could have duplicate subobjects (data from ios inherited into ostream and istream).– Upcasting an iostream pointer to an ios object creates a problem.

Two ios subobjects could exist: which one is used?

– Ambiguous, results in syntax error (of course, iostream does not actually have this problem)

ios

ostreamistream

iostream

Page 40: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

21.12 Multiple Inheritance and virtual Base Classes (II)

• Use virtual base class inheritance– only one subobject of the base is inherited into the multiply derived class.

Second Derived Class

Base Class

First Derived Class

Multiply-Derived Class

virtual inheritance

virtual inheritance

Page 41: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Outline1 // Fig. 21.15: fig21_15.cpp

2 // Attempting to polymorphically call a function

3 // multiply inherited from two base classes.

4 #include <iostream>

5

6 using std::cout;

7 using std::endl;

8

9 class Base {

10 public:

11 virtual void print() const = 0; // pure virtual

12 };

13

14 class DerivedOne : public Base {

15 public:

16 // override print function

17 void print() const { cout << "DerivedOne\n"; }

18 };

19

20 class DerivedTwo : public Base {

21 public:

22 // override print function

23 void print() const { cout << "DerivedTwo\n"; }

24 };

25

26 class Multiple : public DerivedOne, public DerivedTwo {

27 public:

28 // qualify which version of function print

29 void print() const { DerivedTwo::print(); }

30 };

31

1. Define base class

1.1 Define non-virtual derived classes

1.2 Define multiply derived class

Page 42: Chapter 21 - Standard C++ Language Additions

2000 Deitel & Associates, Inc. All rights reserved. 2000 Deitel & Associates, Inc. All rights reserved.

Outline

1.3 Create class objects

1.4 Create an array of base class pointers.

2. Initialize array elements

Program Output

32 int main()

33 {

34 Multiple both; // instantiate Multiple object

35 DerivedOne one; // instantiate DerivedOne object

36 DerivedTwo two; // instantiate DerivedTwo object

37

38 Base *array[ 3 ];

39 array[ 0 ] = &both; // ERROR--ambiguous

40 array[ 1 ] = &one;

41 array[ 2 ] = &two;

42

43 // polymorphically invoke print

44 for ( int k = 0; k < 3; k++ )

45 array[ k ] -> print();

46

47 return 0;

48 }

Compiling...Fig21_15.cppfig21_15.cpp(39) : error C2594: '=' : ambiguous conversions from 'class Multiple *' to 'class Base *'

The address of both is implicitly converted to a base class pointer. This is ambiguous because class Multiple has duplicate subobjects inherited from Base.

If DerivedOne and DerivedTwo had used virtual inheritance, no errors would result and the objects will be printed.