Presentation is loading. Please wait.

Presentation is loading. Please wait.

Chapter 7 CS 3370 chapter 7 CS 3370 – C++ Classes.

Similar presentations


Presentation on theme: "Chapter 7 CS 3370 chapter 7 CS 3370 – C++ Classes."— Presentation transcript:

1 Chapter 7 CS 3370 chapter 7 CS 3370 – C++ Classes

2 Read-Only Member Functions
Chapter 7 CS 3370 Read-Only Member Functions Every non-static member function receives a hidden parameter named this The type of this for C::f: void C::f(C * const this, …){…} a const pointer not a pointer-to-const To guarantee a method doesn’t change data, we want: void C::f(const C * const this, …) {…} How to declare it?

3 const Member Functions
Chapter 7 CS 3370 const Member Functions The this parameter is not visible so we can’t adorn it Solution: add const after the parameter list: void C::f(…) const {…} Declare all member functions that don’t change data as const

4 “Exceptions” to const Member Functions
Chapter 7 CS 3370 “Exceptions” to const Member Functions You can declare some data members to be mutable Even const member functions can change them Useful for implementation detail that doesn’t affect users e.g., cache information const is a “user-view” thing. See also: mutable.cpp.

5 inline Member Functions
Chapter 7 CS 3370 inline Member Functions Work just like inline regular functions put body in header file a hint to the compiler Additional case for member functions: when you define the body of a member function inside the class definition, it is implicitly inline

6 Related Non-Member Functions
Chapter 7 CS 3370 Related Non-Member Functions Not all functions related to an abstraction can (or should) be member functions stream operators can’t be member functions the first argument is the stream, not the object most binary operators should not be member functions for symmetric implicit conversions (discussed later) They are still part of the abstraction declare them in the header file along with the class definition This is known in C++ as the Interface Principle

7 Chapter 7 CS 3370 Friends Since non-member functions may be part of an abstraction, they are entitled to access to non-public data Such functions are called friends getters not required! (and rarely recommended) Declare friends inside the class granting access if not currently in scope, the compiler will look for friends in the scope containing the class unless they are defined with bodies directly inside the host class(!) Declaring a class a friend allows all of its member functions access to the host class’s members { … friend class Foo; You shouldn’t always have getters or setters anyway!

8 In-Class Initializers
Chapter 7 CS 3370 In-Class Initializers Like Java and C#, you can specify initializers for data members in the class definition new in C++11 always execute before any constructor does good practice for built-in types Static data members must be const to use in-class initialization No need to define space externally for const static data members. struct Foo { int x = 0; const static int y = 1; // No other init. needed };

9 Constructors Execute after an object’s memory is allocated
Chapter 7 CS 3370 Constructors Execute after an object’s memory is allocated Used to initialize an object’s memory Which constructor executes depends on arguments passed Execute after sub-objects are initialized Base classes and sub-objects initialize first Example: initMembers.cpp

10 Initializing Member Objects Default Behavior
Chapter 7 CS 3370 Initializing Member Objects Default Behavior Member objects are default-initialized in declaration order class types run the default constructor built-in types are not initialized by default you should use in-class initializers, initializer lists, or a constructor See initInt.cpp, defaultinit.cpp “Zero Initialization”: Occurs with an explicit call to a default ctor Even with built-ins: int x = int( ); // 0 See defaultinit2.cpp

11 A Simple String Class Manages a char buffer
Chapter 7 CS 3370 A Simple String Class Manages a char buffer #include <cstring> #include <iostream> class String { char* data; public: String(const char* s = "") data = new char[std::strlen(s) + 1]; std::strcpy(data,s); } ~String() {delete [] data;} int size() const {return std::strlen(data);} char getAt(int pos) const {return data[pos];} void setAt(int pos, char c) const {data[pos] = c;} void display() std::cout << data << '\n'; };

12 Using class String int main() {
Chapter 7 CS 3370 Using class String int main() { String s = "hello"; // same as String s("hello"); for (int i = 0; i < s.size(); ++i) cout << "s[" << i << "] == " << s.getAt(i) << std::endl; String empty; std::cout << '"'; empty.display(); std::cout << "\"\n"; } /* Output: s[0] == h s[1] == e s[2] == l s[3] == l s[4] == o "" */

13 Strange Behavior int main() { String s = "hello";
Chapter 7 CS 3370 Strange Behavior int main() { String s = "hello"; String t = s; // same as String t(s); t.setAt(0,'j'); s.display(); } /* Output: jello a.out(4603) malloc: *** error for object 0x : pointer being freed was not allocated */ Shallow copy. Strings constants are immutable.

14 Initialization vs. Assignment
Chapter 7 CS 3370 Initialization vs. Assignment Initialization occurs only once, right after an object is created always by some constructor Assignment occurs only after an object has been initialized via operator= Which constructor executed in the previous slide?

15 Chapter 7 CS 3370 The Copy Constructor Initializes a new object as a copy of an existing object of the same type or of some convertible type Has signature T::T(const T&) Copies each member across using their own copy constructors, recursively Generated by the compiler But you can override it (and sometimes should)

16 Compiler-generated Copy Ctor
Chapter 7 CS 3370 Compiler-generated Copy Ctor String(const String& s) : data(s.data) {} // Identical here to: { data = s.data; } (because pointers are not objects, and hence are not default-initialized.)

17 Chapter 7 CS 3370 Shallow Copy s::data hello\0 t::data

18 Problems with Shallow Copy
Chapter 7 CS 3370 Problems with Shallow Copy If you have a pointer as a data member, a shallow copy is probably not what you want Multiple pointers point to the same memory If you de-allocate the data member in one object, you have created a likely fatal situation in the other (“double delete”)

19 Chapter 7 CS 3370 Deep Copy Classes with pointer members representing a dynamically allocated resource should offer a deep copy: Allocate fresh resources Initialize it

20 A “Deep Copy” Copy Constructor
Chapter 7 CS 3370 A “Deep Copy” Copy Constructor String(const String& s) { data = new char[strlen(s.data)+1]; strcpy(data, s.data); }

21 Passing Objects by Value
Chapter 7 CS 3370 Passing Objects by Value Rarely done for non-built-in types Objects are often returned by value, though Because new values are often created A copy is made Therefore, a constructor executes But which constructor?

22 Which Constructor? Not always the copy constructor
Chapter 7 CS 3370 Which Constructor? Not always the copy constructor Depends on the argument(s) via overload resolution As simple as that! Example: trace.cpp

23 More Strange Behavior After coding the Copy Constructor
Chapter 7 CS 3370 More Strange Behavior After coding the Copy Constructor Why does changing t affect s below? int main() { String s = "hello"; // same as String s("hello"); String t; t = s; t.setAt(0, 'j'); s.display(); } /* Output: jello a.out(4767) malloc: *** error for object 0x : pointer being freed was not allocated */

24 Object Assignment Uses operator= Generated by the compiler
Chapter 7 CS 3370 Object Assignment Uses operator= named the “copy assignment” operator (vs. +=, -=, …) must be a member function Generated by the compiler assigns each data member individually does a shallow copy You can override it and sometimes should, just like the copy constructor

25 Compiler-generated Assignment
Chapter 7 CS 3370 Compiler-generated Assignment String& String::operator=(const String& rhs) { data = rhs.data; return *this; } s hello\0 t

26 What should String::operator= do?
Chapter 7 CS 3370 What should String::operator= do? Allocate new heap space Copy characters to target  Delete the old heap space  Return *this Avoid unnecessary self-assignment An optional but encouraged optimization And watch the order you do things in!

27 Correct Assignment String& String::operator=(const String& s) {
Chapter 7 CS 3370 Correct Assignment String& String::operator=(const String& s) { if (&s != this) // avoid self-copy char* new_data = new char[strlen(s.data)+1]; strcpy(new_data, s.data); // copy delete [] data; // delete old data = new_data; // store new } return *this; // for chaining of assignments The return enables a = b = c;

28 Value Types Types that “do what the ints do”
Chapter 7 CS 3370 Value Types Types that “do what the ints do” ints are copied freely as tempoaray parameters and return values Value types you define should behave the same way if you want them to They may need: a copy constructor an copy-assignment operator a destructor The compiler may generate these for you!

29 Types of Constructors Default Constructor Copy Constructor
Chapter 7 CS 3370 Types of Constructors Default Constructor a constructor that can be called with no arguments Copy Constructor called when you create a new object initialized by an existing one e.g., passing objects or returning objects by value Move Constructor advanced topic (discussed shortly) – new in C++11 Others you may define

30 Compiler-Generated Constructors
Chapter 7 CS 3370 Compiler-Generated Constructors Called “synthesized” constructors The compiler generates a default constructor only if you define no constructors at all it “default-initializes” all data members calls default constructors for embedded members built-ins with no in-class initializer remain undefined The compiler generates a copy constructor only if you don’t

31 Keeping the Synthesized Default Ctor
Chapter 7 CS 3370 Keeping the Synthesized Default Ctor What if you want to define other constructors, but keep the synthesized default constructor? Possible in C++11 with =default

32 Constructor Initializer Lists
Chapter 7 CS 3370 Constructor Initializer Lists For passing parameters to constructors of embedded data objects (and base classes) Very important! if not used, the data member will automatically be default-initialized before the constructor for the complete object is called it will be “initialized” twice if you do it with an assignment in the complete object’s constructor never initialize a member object by assignment in the body of the constructor! See badInit.cpp, goodInit.cpp, constMem.cpp

33 Removing a Synthesized Operation
Chapter 7 CS 3370 Removing a Synthesized Operation Use =delete in the declaration and define no body, of course convenient for disabling copy or assignment Can apply to: default constructor (rare) copy constructor assignment operator Cannot delete the destructor!

34 Delegating Constructors
Chapter 7 CS 3370 Delegating Constructors aka “forwarding constructors” (new in C++11) other languages use direct calls to this(…) C++ uses the initializer list Allows factoring common code for multiple constructors Just call the shared constructor with the appropriate signature in the initializer list.

35 Nested Types You can define types inside of classes Two ways:
Chapter 7 CS 3370 Nested Types You can define types inside of classes Two ways: with using (or typedef) by defining a nested class The full type name is Screen::pos

36 Nested Classes Can define totally inside the class or…
Chapter 7 CS 3370 Nested Classes Can define totally inside the class or… Can just declare inside and define outside the class

37 Name Lookup Inside Classes
Chapter 7 CS 3370 Name Lookup Inside Classes 1) Look for a local definition in the method itself 2) Failing that, look in the class definition find non-static members via this find static members in the class 3) Otherwise follow normal scope rules (enclosing scopes…)

38 Move Semantics New in C++11 An efficiency technique New Features:
Chapter 7 CS 3370 Move Semantics New in C++11 An efficiency technique related to value semantics New Features: rvalue references move constructor move assignment std::move std::forward

39 Copying vs. Moving Very often, copies are temporaries
Chapter 7 CS 3370 Copying vs. Moving Very often, copies are temporaries they have no name they exist a very short time There are times when we can avoid a full copy of a temporary by “stealing” its resources it won’t need them anyway We need to discern between a temporary (always an rvalue) and an object that persists beyond the current expression (usually an lvalue)

40 rvalue References rvalue references only bind to temporaries
Chapter 7 CS 3370 rvalue References rvalue references only bind to temporaries Uses the && syntax: T::T(T&& t){…} // A “move” constructor T& operator=(T&& t) {…} // “Move” assignment Since t is a temporary we can just grab its inner data often these are just pointers (that’s where the savings is) We must leave t in a destructible state See trace2.cpp, move.cpp

41 Items to Note We now call “regular” references “lvalue references”
Chapter 7 CS 3370 Items to Note We now call “regular” references “lvalue references” rvalue references only represent objects about to be destroyed i.e., temporary, nameless values these references are unique (no other access exists) Variables are lvalues in their scope even if they were declared with &&!!! see next slide

42 Variables are Lvalues Because they persist to the end of their scope
Chapter 7 CS 3370 Variables are Lvalues Because they persist to the end of their scope Temporaries have no such lifetime – they are ephemeral From the book: int &&rr1 = 42; // Okay; literals are rvalues int &&rr2 = rr1; // Error! Variables are lvalues int &&rr3 = std::move(rr1); // Okay: move converts lvalue→rvalue Only use std::move if the value can be immediately discarded after use! Because it is about to be stolen

43 Chapter 7 CS 3370 Why Do We Care? Move semantics provide a tremendous efficiency with containers When a container has to grow/reallocate its storage, it is often much faster to move objects than to copy them But the object type must provide move semantics: a move constructor and assignment operator otherwise copy semantics will be used (as usual) Containers provide top-level move semantics as well moving the entire container at once


Download ppt "Chapter 7 CS 3370 chapter 7 CS 3370 – C++ Classes."

Similar presentations


Ads by Google