程序代写 COSC1076 Week 11

Advanced Topics
COSC1076 Week 11

Skill Progression in this Course

Copyright By PowCoder代写 加微信 powcoder

Software Design
Implementation
Week 11 | Advanced Topics COSC1076

Abstract Classes Operator Overloading Lambda Functions Code Re-use Extraneous Copying
Week 11 | Advanced Topics COSC1076

Abstract Classes

Abstract Classes
An Abstract Class defines methods that must be implemented by derived classes
• It may also defined public and protected fields that derived classes may use • It should specify any contracts (pre- and post-conditions) for the methods
You cannot create an object of an Abstract Class. • You may only create objects of derived classes
The class still defines a valid polymorphic valid type.
• Thus you can have pointers and references to an abstract class type. • You can cast between abstract class types
Abstract Classes are similar to interfaces in Java
Week 11 | Advanced Topics COSC1076

Abstract Classes
An Abstract Classes is created by making one or more methods of the class “abstract” (by ‘setting it to zero’).
• All abstract methods must be virtual
class LinkedList {
virtual int size() = 0;
virtual void clear() = 0;
virtual int get(int i) = 0;
Week 11 | Advanced Topics COSC1076

Benefit of Abstract Classes
Abstract Classes allow “generic” or common behaviour of an ADT to be defined
• Without having to provide a direct implementation
• Allows implementations of the ADT to be swapped without changing any of the types within code that uses the ADT defined on an abstract class
Abstract classes can provide code implementations
• Allows for code-reuse through the common base class
Should only be used where the benefit to have polymorphic types or multiple varying implementations is required
Example use:
• Abstract I/O in C++
-std::istream
-std::ostream
Week 11 | Advanced Topics COSC1076

Operator Overloading

Operator Overloading
Permits classes to make use of the 38 C++ operators, including: • Comparison operators: ==, !=, <, <=, >, >=
• Arithmetic operators: +, -, *, /, %, ^, +=, -=, etc.
• Increment/Decrement: ++, —
• Assignment operator: = • I/O operators: <<, >>
• Access: [], *, ->, &
Generally operators can be divided into:
• Operators that do not modify the class
• Operators that modify the class, and return it • Operators that return a new class
https://en.cppreference.com/w/cpp/language/operators
Week 11 | Advanced Topics COSC1076

Operator Overloading
Operators can be overloaded through:
• Methods (member functions) on a class • Functions external to the class
For this course we will stick to member functions, though the concept for function versions is very similar
Week 11 | Advanced Topics COSC1076

Operator Overloading
In an expression:
lhs rhs
The overloaded operator method is called on the object on the left-hand side • The object on the right-hand side is passed as a parameter
Week 11 | Advanced Topics COSC1076

Comparison Operators
All comparison operators take the form:
bool operator???(const Class& rhs) const;
• They return a bool
• Take the RHS as a constant reference • Are a const method
You have to implement any comparison operator you wish to use: • But, only really need to implement two:
• The other comparison operators are implemented from these
bool operator==(const Class& rhs) const;
bool operator<(const Class& rhs) const; Week 11 | Advanced Topics COSC1076 Access Operator The square bracket access operator[] type& operator[](const int index); • Note how it returns a reference! • This is a reference to the index being accessed • Allows the value at the index to be updated Week 11 | Advanced Topics COSC1076 Arithmetic Operators (self modifying) Some arithmetic operators directly modify the object itself: • Still return a reference to the current object - This is for operator chaining reasons - ALL c++ operators return a value - none are void • The parameter can be of any desirable type to add to the object Object& operator+=(const Object& other); Object& operator+=(int value); Week 11 | Advanced Topics COSC1076 Arithmetic Operators (new) Some arithmetic operators generate a new object: Object operator+(const Object& other) const; • Generate a new object - The new object is the result of the arithmetic operation • Does NOT modify the object itself - This is why it is const Week 11 | Advanced Topics COSC1076 Assignment Operator Replaces the contents of the current object with a COPY of the contents of the object passed as the parameter: Object& operator=(const Object& other); • Differs from a copy constructor as this modifies an existing object • Returns a reference to the current object (after modification) Week 11 | Advanced Topics COSC1076 Increment Operators Pre-increment Object& operator++(); • Modifies the existing object • Returns a reference to the existing object Post-increment Object operator++(int); • COPIES the object first • Then increments • Then returns the copy (not it is not a reference) • Requires a different parameter (which is ignored) to permit the overloading Week 11 | Advanced Topics COSC1076 Stream Operators A stream operator MUST be defined as non-member functions. That is, they cannot be methods of the class, but defined outside of the class. std::ostream& operator<<(std::ostream& os, other& vec); • Outputs the operator to the provided output stream • Returns a reference to the stream that was written to Week 11 | Advanced Topics COSC1076 Lambda Functions Lambda Functions Lambda Functions are function that sit within the scope of another function They allow for: • Local code re-use to avoid duplication of the same logic • Prevent are large scope or namespace (such as a class or C++ file) to be “polluted” by additional functions/methods which should really be contained to a small local scope Issues include: • Should be kept small and simple, otherwise they causes code-readability issues • May result in code duplication (of the same lambda function) across a large scope/file since non of those methods export the duplicated logic Week 11 | Advanced Topics COSC1076 Lambda Functions Lambda Functions work identically to normal function/methods, with one exception • The function can capture variables from the scope of the external function • Variables can be captured: - By explicit name (as a copy or reference) - By default (capture all external variables that are used) - [=] by copy - [&] by reference auto name = [capture]( params ) { Week 11 | Advanced Topics COSC1076 Code Re-use Class: Code Re-use Where possible, a derived class should re-use as much code as possible from it’s base class(es), rather than overriding and re-implementing methods Things to consider include: • If a method requires no changes, it should not be overridden • An overriden method should call the base class version for common code • If multiple derived classes use similar logic, that should be placed as a protected method in the base class Week 11 | Advanced Topics COSC1076 Polymorphism: Code Re-use The most appropriate class should be used in the code Things to consider include: • A good principle is to use the most “general” base class for any block of code - This is determined by what methods need to be called - What other code may be passed the object • Typecasting should be avoided Week 11 | Advanced Topics COSC1076 Generics: Code Re-use Place logic that is identical, except for the types involved, into a single place Allow the compiler to generate the necessary code for each type Week 11 | Advanced Topics COSC1076 Operator Overloading: Code Re-use Allow re-use of standard operators and concepts when writing code • Such as assignment, comparison, I/O, etc. Reduces the need to manually specify custom functions/methods • See Java .equals(), etc. Can make code more easy to “intuitively” interpret • Such as operator+() on std::string Week 11 | Advanced Topics COSC1076 Function: Code Re-use Have seen in many courses the purpose of modularity Splitting code into functions allows those functions to be re-used, rather than re-written Week 11 | Advanced Topics COSC1076 Lambda Function: Code Re-use Allow the principle of function re-use, but keep that re-use to a localised scope Week 11 | Advanced Topics COSC1076 Warning: DANGER! As with all discussions in this course there is a but... • Having too many external code-dependencies (ie library code-reuse) • Ensuring external dependencies are actually correct and necessary Week 11 | Advanced Topics COSC1076 Warning: Leftpad Week 11 | Advanced Topics COSC1076 An iterator is a generalised pointer into a container • The pointer “deferences” to a specific element of the container • The iterator may be “stepped” to access the “next” element of the container • The order of iteration depends on the container C++14 supports various types of iterators with various restrictions • For this discussion, we stick to random-access iterators C++ STL containers have methods to work with iterators • begin() - an iterator pointer to the “first” element of the container • end() - an iterator pointer to the element “beyond” the “last” element of the container Week 11 | Advanced Topics COSC1076 Typical Use: for(std::vector::iterator it = vec.begin();
it != vec.end();
cout << "vec[?] = " << *it << endl; Iterators are “stepped” using: • Increment/decrement operators - preferred • Addition/Subtraction operators - possible in certain circumstances The value “pointed to” by an iterator is accessed by • Dereferencing the iterator Week 11 | Advanced Topics COSC1076 Typical Use: for(std::vector::iterator it = vec.begin();
it != vec.end();
cout << "vec[?] = " << *it << endl; The iterator type is typically defined within a class: • In general, use ::iterator
Iterators can be compared (==/!=)
• Two iterators are the same if they point to the same element of the container
Week 11 | Advanced Topics COSC1076

• Provide a generic, type independent approach to iterating through the elements of a container
• Algorithms can be written that operate over iterators – Rather than the container directly
• Iterators are frequently used within the C++ STL – Not explored in depth in this course
• Typically more efficient at accessing elements of a container than directly random-access methods (if iteration is desired)
Week 11 | Advanced Topics COSC1076

What does the assignment operator (=) do?

What actually happens in a statement?

Case 1: Assignment with Classes
Assignment operator does an explicit duplication/copy If no assignment operator?
Vector v1;
Vector v2;
Week 11 | Advanced Topics COSC1076

Case 2: Passing by Value
Pass-by-value must duplicate the object, • Calls the copy constructor
Vector v1;
printVector(v1);
void printVector(Vector v) {
for (int i = 0; i != 10; ++i) {
cout << "v1[" << i << "]: " << v[i] << endl; Week 11 | Advanced Topics COSC1076 Case 3: Returning an Object In C++14, according to the language specification, gives a copy • Return Value Optimisation converts this is a direct initialisation • Remove the copy Vector v1 = newVector(); Vector newVector() { v[0] = 42; Week 11 | Advanced Topics COSC1076 Case 4: Increment, pre vs post There is a significant difference between pre and post increment operators • The optimiser may not be able to “optimise-out” the unnecessary copy Vector v1; for (int i = 0; i != 5; i++) { cout << "i = " << i << endl; printVector(v1); Week 11 | Advanced Topics COSC1076 程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com