1 / 32

C++ Certificate Program C++ Intermediate

C++ Certificate Program C++ Intermediate. Const. Const in C++. Differ greatly than what is defined in C Const objects, const methods, const declarations (references or pointers) Member constants may have class or instance scope. Constant Objects.

jin
Download Presentation

C++ Certificate Program C++ Intermediate

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. C++ Certificate ProgramC++ Intermediate Const

  2. Const in C++ • Differ greatly than what is defined in C • Const objects, const methods, const declarations (references or pointers) • Member constants may have class or instance scope

  3. Constant Objects • Const objects are not modifiable (once created) - cannot assign to or call non-const member functions • Review – initialization occurs at declaration (not assignment of a value after object creation) • Initialization is only place where values can be set (and all const objects must be initialized) int main() { int const y (0); Truck const bigTruck (“Mack”); y = 50; // illegal! }

  4. Simple Const Objects • Simple const objects (variables) are of a built-in type, or classes without constructors (other restrictions apply as well) • Storage is not assigned by default • Initial values must be compile-time computable

  5. Simple Const Variables and Storage • Ideally, the compiler would like to treat a constant like a define, except with type checking / safety • No storage would be allocated for the constant, which would result in a text replace where used int const myConst = 256; • Every use of myConst would be replaced with 256 (thus no storage allocated)

  6. When Storage Must be Allocated • If the address of a const object is taken, storage must be allocated int const y = 256; int const& iref = y; // y now needs storage inn const* iptr = &y; // same here

  7. Linkage • Unlike C, constants in C++ have internal linkeage, necessary to avoid allocating storage. float const pi; // legal in C, not in C++ • If external linkage forced (address taken), causes storage allocation float const pi = 3.1415….; // file1: definition extern float const pi; // file2: declaration, // causes storage allocation

  8. Non-Simple Const Objects • Objects of class type can be also be const Employee const myBoss(“Bill”); • Object can’t be placed in read-only memory • Object typically can’t be “optimized away” • Constructor invoked when object created (as usual)

  9. Constant Literal Folding • If possible, compilers will perform constant literal folding • Folding is the reduction of constants at runtime int x = 256*2+10; // will be reduced to 522 int const y = 1024; // no storage! int z = x + y - 100; // reduced to 546

  10. Examples int const i (100); // note alternate initialization // syntax – parens instead of ‘=‘ int const j (i +10); // value from const expression int const * address (&j); // forces storage char buff[j+10]; // constant folding int func() { int const c = cin.get(); // not known at compile time int const c2 = c*2; }; // c goes out of scope

  11. Class vs Instance Scope • Constant class member may have class scope (static - same value for all instances of the class) or instance scope (each object will have a potentially different value)

  12. Class Scope Constants class X { public: static const int size = 256; }; • All instances of class X have a size member of the value 256. • Potentially, no storage will be allocated, and the constant is subject to constant folding • Definition must still be provided in implementation file // .cpp file int const X::size;

  13. Instance Scope Constants • Instance scope constants must be initialized in initialization list (good style for all member data, of course), may not later be altered class X { public: X(int s) : size(s) {} private: int const size; }; • Storage is allocated, not subject to constant folding (since value is set when object is created)

  14. Constant Pointers • Pointer may be const, the value pointed to may be const, or both int const* ptr1; // int is const, pointer is not const int* ptr2; // equivalent to the above! int* const ptr3; // const pointer to char int const* const ptr4; // const pointer to const int const int* const ptr5; // equivalent to above

  15. References • Review: references are similar to automatically dereferenced pointers, where pointer itself is const, but object pointed to may or may not be const • Reference must be initialized at time of declaration, just like any other constant int y; int& iref = y; ++iref; // fine, the value referenced is not const int const& ciref = iref; ++ciref; // illegal, the value pointed at is // declared to be const

  16. References • A reference itself may not be modified (syntax makes it difficult to do so, as well) • Because a reference by definition is const, it is redundant, and illegal, to explicitly declare them as such int const& iref const = y; // doh! illegal

  17. Const Declarations • Pointers to const data, const references, const member functions provide interface usage and declaration intent - actual objects in use may or may not be const int x; int const* y =&x; int const& z = x; x = 10; // legal, x is not const *y = 10; // not legal z = 10; // not legal void f(int const & a); f(x); // x will not be modified during f lifetime

  18. Const Declaration Style • Reading declarations: work from identifier outwards, const modifies what is “closest” • Traditional const declaration places const to the left of the type: const int x = 50; void f(const int&); • Some developers (still a minority) use “newer” const placement style (for consistency, since const always to right of what is const): int const x = 50; void f(int const&);

  19. Const Conversions • Non-const object can always be converted to const; converse is not true void f(int const* x); void g(int* x); int* a; int const* b; f(a); // legal f(b); // legal g(a); // legal g(b); // error! Not legal

  20. Const Part of Type • Const is part of the type and part of a function signature, crucial to overloading and general type distinctions • Many developers place pointer or reference symbol next to type to reinforce concept: int* x; // x’s type is int* int& y(a); // y’s type is int& int const& z (a); // z’s type is const int &

  21. Instance Scope References • As with instance scope constants, instance scope references must be initialized in constructor initialization list class X { public: X(int val1, float val2) : myRef(val1), yourRef(val2) {} private: int& myRef; float const& yourRef; };

  22. Pasing Function Args by Const Value • Sometimes used for documentation purposes int func(int const i); • Passing by value means copy of arg is made, const in this context is meaningless • However, can be meaningful inside the function implementation, which may not alter the value

  23. Returning by Const Value • Return by const value may be useful (although it appears to be meaningless) because a temporary is created when dealing with user-defined types X func(); // return val may be used as an L-value X const func(); // cannot be used as an L-value

  24. Example - Eckel, page 346 class X { int i; public: X(int ii = 0) : i(ii) {} void modify() {++i;} }; X f5() { return X(); } X const f6() { return X(); } void f7( X& x ) { x.modify(); } int main() { f5() = X(1); // legal – non-const return value f5().modify(); // legal (should it be allowed, though?) f7(f5()); // causes warning f6() = X(1); // compile–time error f6().modify(); // compile–time error f7(f6()); // compile–time error }

  25. Temporaries • Compiler may create temp objects in an expression X(Y()); // instance of Y is temporary a + b + c; // two temporaries created • Created and destroyed by the compiler; user code cannot directly access them • Built-in type temporaries are const (class type temporaries are not const, however)

  26. Const Member Functions • A const method (member function) cannot modify any self / “this” data (member data) class X { public : X(); // getState will not modify state of X int getState() const { return y; } private: int y; };

  27. Passing and Returning Addresses • Pointer or reference (review: reference is an “alias” for an existing object) • Should be made const if at all possible to allow for use with const objects • Return const pointer or reference if wish to negate its use as a lval, or otherwise modify its value

  28. Recommendation • For argument passing, choose reference first, const if possible – this eliminates questions that pointer flexibility may bring void f (int * p); // can p be null? Does it point to a single object // or an array of objects? • In general, use const whenever possible • Allows the compiler to make certain optimizations • Documents intent to other users

  29. Const in Classes • Const class instances • Defined in the same manner as built-ins: int const y; X const x(1); • Const member functions • Const member data

  30. Mutable • What does it mean for an object to be const? • Bitwise vs logical (memberwise) constness • Both compiler and linker enforce class constness • Const member functions may not change object members • Only const methods may be invoked on a const object • Const methods may not change state • In lieu of const_cast, the mutable keyword declares a member as modifiable in a const method

  31. Mutable Example class X { public: X(int a = 0, b = 0) : x(a), y(b) {} int foo(); int bar() const { ++x; } // illegal int doh() const { ++y; } // OK, mutable private: int x; mutable int y; }; int main() { X const x(5,10); x.foo(); // illegal – can’t invoke non-const methods // on const object x.doh(); // OK }

  32. Volatile • Tells compiler it cannot make assumptions about a variable in between uses • Multithreading, multitasking, or interrupt activity may change value of the variable outside of statement sequences • Compiler will often optimize with registers; volatile turns off this optimization, makes sure variable access uses memory address

More Related