DOC PREVIEW
CALTECH CS 11 - Advanced C++

This preview shows page 1-2-14-15-29-30 out of 30 pages.

Save
View full document
View full document
Premium Document
Do you want full access? Go Premium and unlock all 30 pages.
Access to all documents
Download any document
Ad free experience
View full document
Premium Document
Do you want full access? Go Premium and unlock all 30 pages.
Access to all documents
Download any document
Ad free experience
View full document
Premium Document
Do you want full access? Go Premium and unlock all 30 pages.
Access to all documents
Download any document
Ad free experience
View full document
Premium Document
Do you want full access? Go Premium and unlock all 30 pages.
Access to all documents
Download any document
Ad free experience
View full document
Premium Document
Do you want full access? Go Premium and unlock all 30 pages.
Access to all documents
Download any document
Ad free experience
View full document
Premium Document
Do you want full access? Go Premium and unlock all 30 pages.
Access to all documents
Download any document
Ad free experience
Premium Document
Do you want full access? Go Premium and unlock all 30 pages.
Access to all documents
Download any document
Ad free experience

Unformatted text preview:

CS11 – Advanced C++ Spring 2012-2013 Lecture 7Today’s Topics n All about casting in C++ q Implicit casting q explicit keyword on constructors q Explicit casting in C++ q mutable keyword and constImplicit Type-Conversions n C++ has implicit type-conversions for primitive types q You don’t explicitly cast from one type to the other q They just happen, without warning! J n Promotions q Value is preserved, no information is lost q Examples: char → int, bool → int n Conversions q Value may actually change or become invalid q Examples: double → char, double → float n Beware! Compiler doesn’t give you much help!Conversion of User-Defined Types n Can define implicit conversion ops for user-types class Rational { public: Rational(int num, int denom); ... // Convert from Rational to double operator double() const; }; q Provides implicit conversion from Rational to double Rational r(1, 2); // r is 1/2 double d = 0.5 * r; q r is converted to double, then multiplication is performedUnexpected Results! n Now you want to print Rational values with << q Print them as “num/denom” q …but, you forgot to implement << n You write this code: Rational r(1, 2); cout << r; q You expect this to print 1/2 q (Or, actually, to not compile since you didn’t implement <<) q But it does compile, and it prints out 0.5 q Not too surprising, just subtle.Crafty Compilers n Compiler sees no << for Rational q “But Rational can be converted to double, and double can be output with <<…” n Problem: q Implicit conversion operations can produce unexpected or undesirable results! q Violates the “Law of Least Surprise” n Moral: q Be very careful with implicit conversion operations q Better yet, don’t use them: double Rational::asDouble() { ... }More Implicit Conversion Options n Single-argument constructors also enable implicit conversions in C++ n Example: Rational(int num = 0, int denom = 1); q Defines default values for arguments q Also allows ints to be converted to Rationals Rational r1(3); // r1 = 3/1 Rational r2 = 5; // r2 = 5/1 r1 = 6; // r1 = Rational(6) q Compiler figures out the conversions to use!Another Implicit Conversion Example n An integer-array class: class Array { ... public: Array(int size); int & operator[](int index); bool operator==(const Array &) const; bool operator!=(const Array &) const; };More Unexpected Results n Want to compare two arrays: Array a(10), b(10); ... for (int i = 0; i < 10; i++) { if (a == b[i]) { ... // Do stuff! } } n Oops; meant to type a[i] == b[i] q But, the code compiles! n What happens: q Compiler guesses this: a == Array(b[i]) q Wrong, not to mention terribly inefficient!Disallowing Implicit Conversions n Compiler should complain in these cases q Don’t want it to make up stuff that compiles, but that you didn’t mean! n Enter the explicit keyword q Added to C++ specifically because of these issues q Can declare constructors to be explicit q C++ won’t use them for implicit conversions n Example: explicit Array(int size);Default Parameters and explicit n If constructor can take just one argument, it will be used as an implicit conversion q …even multi-arg constructors with default values n Rational example again: Rational(int num = 0, int denom = 1); q Defines default values for arguments q Also provides implicit conversion from int n Can also use explicit here: explicit Rational(int num = 0, int denom = 1); q No longer allows implicit conversions from intExplicit Casts in C and C++ n C has one explicit cast operator for everything q Can convert between related types n e.g. double to int q Can cast pointers to different types n e.g. void* to float*, or float* to char* q Can cast pointers to int, and vice versa q Can cast away const-ness q Many unsafe or potentially unsafe scenarios! n C++ provides four explicit casting operators q Breaks down different kinds of casts into explicit operations q Provides more type-safety checks at compile-time, run-time q Easier for programmers to understand, tooC++ Cast Operations n const_cast q Casts away const-ness n static_cast q Performs safe conversions between related types, using static (compile-time) type information n dynamic_cast q Uses runtime type information to safely cast down or across class hierarchies n reinterpret_cast q For all the dangerous stuff.Removing const Constraints n const_cast removes const constraints q T const_cast<T>(const T value) n Not for changing the type of value ! q Using const_cast to change types will not compile n Examples: void output(SpecialWidget *psw); const SpecialWidget csw; output(&csw); // COMPILE ERROR output(const_cast<SpecialWidget*>(&csw)); // OK Widget *pw = new SpecialWidget(); output(const_cast<SpecialWidget*>(pw)); // COMPILE ERRORCached Values and const n const_cast sometimes used when objects cache temporary values that are expensive to compute class Date { ... string cache; bool cacheValid; void updateCacheVals(); // sets cache value public: ... string stringRep() const; }; q stringRep() returns a string version of the date value q Cache the result, as long as date value doesn’t changeCached Values and const (2) n Implementation of stringRep() string Date::stringRep() const { if (!cacheValid) { // Type of this is "const Date *", so // cast to non-const Date * Date *mut = const_cast<Date *>(this); mut->updateCacheVals(); mut->cacheValid = true; } return cache; } q this is const because the member function is const q Must cast away const to update cached values!Cached Values and const (3) n That solution isn’t very elegant. n Also, it might not actually work! q If original variable is declared as const, casting away const is not guaranteed to work on all implementations n e.g. compiler or OS might store variable in read-only


View Full Document

CALTECH CS 11 - Advanced C++

Download Advanced C++
Our administrator received your request to download this document. We will send you the file to your email shortly.
Loading Unlocking...
Login

Join to view Advanced C++ and access 3M+ class-specific study document.

or
We will never post anything without your permission.
Don't have an account?
Sign Up

Join to view Advanced C++ 2 2 and access 3M+ class-specific study document.

or

By creating an account you agree to our Privacy Policy and Terms Of Use

Already a member?