Presentation is loading. Please wait.

Presentation is loading. Please wait.

C++ Training Datascope Lawrence D’Antonio Lecture 6 An Overview of C++: What is Polymorphism? - Coercion.

Similar presentations


Presentation on theme: "C++ Training Datascope Lawrence D’Antonio Lecture 6 An Overview of C++: What is Polymorphism? - Coercion."— Presentation transcript:

1 C++ Training Datascope Lawrence D’Antonio Lecture 6 An Overview of C++: What is Polymorphism? - Coercion

2 What is polymorphism?  Different types of objects respond to the same message and use the appropriate method. Polymorphism Universal Ad-hoc Parametric Subtype Overloading Coercion

3   A coercion is an implicit type conversion. This allows the programmer to omit a type cast.   There are three types of coercions:   Compiler defined (such as promotions, derived  base)   Constructor   User defined

4 Compiler defined coercions   Simple example double x; x = 2; //2 promoted to double

5 Function call coercions void foo(double x) { //... } //foo() can be called with any type that can be //converted to double foo((short) 4); foo(‘a’); foo(3L); foo(2.3F);

6 Is this legal? #include void f(char a, int b) { std::cout << a << b << '\n'; } void f(int a, char b) { std::cout << a << b << '\n'; } main() { f('a','b'); return 0; }

7 Not legal, it’s ambiguous.

8 Coercion vs. Overloading example 3 + 4; 3 + 4.0; 3.0 + 4; 3.0 + 4.0; How does this work?

9 Explanations of example   Four overloaded versions of operator +   Two overloaded versions of operator +, one for integers, the other for doubles. The middle two calls in the example would use coercion.   One version of operator +, for doubles. The first three calls in the example would use coercion.

10 Derived to Base Conversion   C++ will implicitly convert a pointer or reference to a derived class to a pointer or reference to the base class. This is because the derived class has a copy of the base class inside it.   A pointer to the base class cannot be converted to a pointer to the derived class.

11 Is this legal? class A {}; class B: public A {}; class C: protected A {}; class D: private A {}; main() { A *pa = new B; pa = new C; pa = new D; return 0; }

12 pa = new B; //Legal, B is an A pa = new C; //Illegal, C is not an A pa = new D; //Illegal, D is not an A In the last two cases, the base class is inaccessible.

13 Is this legal? class A {}; class C: protected A { public: void foo() { A *pa = this; } }; class D: private A { public: void foo() { A *pa = this; } }; main() { C c; c.foo(); D d; d.foo(); return 0; }

14 Yes, it’s legal. Protected and private inheritance exemplify a has-a relationship, rather than an is-a relationship. Member functions are allowed to convert pointer to derived into pointer to base.

15 Pointer to Member Conversions   What is the relationship between a pointer to member of a base class and a derived class?

16 Is this legal? struct A { int a; }; struct B: public A { int a; }; main() { A a; B b; int A::*pa = &B::a; int B::*pb = &A::a; return 0; }

17 Complicated. int A::*pa = &B::a; is illegal. Can’t convert pointer to derived member to a pointer to base member. int B::*pb = &A::a; Is legal. Can convert pointer to base member to a pointer to derived member.

18 Conversion Constructors   Constructors that take a single argument can be thought of as a type conversion. struct X { X(int); };   So that any code that expects an object of class X can be passed an int that will then be converted to an X.

19 Is this legal? struct X { X(int){} }; void f(const X &) {} void g(int) {} void g(X) {} main() { f(3); g(4); g(X(5)); return 0; }

20 f(3); //Legal, you can create a temp //object X(3), which is passed to //f() g(4); //Legal, calls g(int) g(X(5)); //Legal, calls g(X)

21 Is this legal? struct X { X(int){} }; void f(X &) {} void g(int) {} void g(X) {} main() { int a = 2; f(3); f(a); g(4); g(X(5)); return 0; }

22 f(3); //Not legal, can’t use temp X object to initialize an X & f(a); //Not legal, can’t use temp X object to initialize an X & g(4); //Legal, as before g(X(5)); //Legal, as before

23 Is this legal? struct X { X(int){} }; struct Y { Y(X) {} }; void f(Y) {} main() { f(3); return 0; }

24 Not legal. Basically, only one level conversions are allowed. Not allowed to convert int to X to Y.

25 Is this legal? struct X { X(int){} }; void f(X) {} void g(int) {} void g(X) {} main() { int a = 2; f(3); f(a); g(4); g(X(5)); return 0; }

26 f(3); //Legal, temp X is passed by value f(a); //Legal, temp X is passed by value g(4); //Legal, as before g(X(5)); //Legal, as before

27 Is this legal? class X { public: X() { std::cout << "Hello\n"; } void foo() { std::cout << "In X::foo()\n"; } }; class Y { X ex; public: Y(X x): ex(x) { std::cout << "World\n"; } void foo() { ex.foo(); } void foo(X x) { x.foo(); } void foo(Y y) { y.foo(); } }; main() { Y y(X()); y.foo(y); return 0; }

28 Not legal! The problem is y.foo(y). foo is not a member of y, which is of non- class type Y ()(X (*)()). This can be fixed with Y y = X();

29 Explicit Constructors   Single argument constructors (or constructors that can be called with a single argument) can lead to unexpected consequences.

30 class X { int x; public: X(int a = 0):x(a) {} }; main() { X ptr_x = 0; //...

31 That was bad!   The programmer probably meant X *ptr_x = 0;   But the compiler performed the conversion X ptr_x = X(0);

32 Solution class X { int x; public: explicit X(int a = 0):x(a) {} }; main() { X ptr_x = 0; //...

33 The compiler will flag the following as an error: X ptr_x = 0; This code implicitly uses the constructor X(int) In order to use this constructor, one must explicitly call the constructor. X ptr_x = X(0);

34 Constructor Rule   Any single argument constructor should be declared explicit.

35 Conversion operators   A user defined operator that converts a user defined object into another type.   The destination type may be a built-in or user defined type.

36 Example class Fraction { int numerator, denominator; public: Fraction(int n = 0, int d = 1): numerator(n), denominator(d) {} //... operator double() const { return static_cast (numerator)/denominator; } };

37 Usage Fraction f(3,4); double d = f; // d is 0.75 double x = f + 2;

38 Is this legal? Fraction f(1,2), g(1,3); Fraction h; h = f + g;

39 Hard to tell! h = f + g; This is legal if there is an overloaded operator + that takes Fraction operands. This is also legal if, in the unlikely case, there was a ctor Fraction(double).

40 Perils of conversion template class Ptr { T *p; public: //... operator bool() const { return p ? true : false; } }; Ptr ptr1; Ptr ptr2; if (ptr1 == ptr2) {/...}

41 The comparison ptr1 == ptr2 is valid because the Ptr s are converted into bools and then compared. So Apples and Oranges can be compared! If operator == were overloaded for type Ptr, then that version would be called.

42 Is this legal? string filename = “data.txt”; ifstream in_file(filename);

43 Not legal! ifstream constructor expects a const char * argument. Legal version: ifstream in_file(filename.c_str());

44 Is this legal? //Let’s define a conversion operator for // string class operator const char*(const string &s) { return s.c_str(); } string filename = “data.txt”; ifstream in_file(filename);

45 Not legal! Conversion operators can only be member functions.

46 C++ is weakly typed class Tupid { public: template operator X { return X(); } };

47 This means that objects of class T can be converted into an object of any (yes, any) type that has a default constructor. Tupid t; int a = t; string s = t; vector v = t;

48 Breaking encapsulation class A { public: void foo() {}; } ; class D: private A { public: A *foo() { A *pa = this; return pa; } }; main() { D d; A *pa = d.foo(); pa->foo(); //Calls A::foo //...

49 Breaking encapsulation 2 class A { int a; public: int *foo() { return &a; } }; main() { A a; int *p = a.foo(); *p = 12;

50 Breaking encapsulation 3 class A { private: int a; }; class B: public A {}; main() { A a; B b; int B::*pb = &A::a; b.*pb = 5; return 0; }

51 Not legal. A::a accesses private data


Download ppt "C++ Training Datascope Lawrence D’Antonio Lecture 6 An Overview of C++: What is Polymorphism? - Coercion."

Similar presentations


Ads by Google