Top Banner
Computer Programming 2 Paul Calder Designing Classes Class: A blueprint for creating objects Flinders University / Computer Programming 2 2 Program Design Look for the objects Think "objects interacting" Nouns and noun phrases Decide on the classes Similar kinds of objects Category nouns "Is-a" relationships Flinders University / Computer Programming 2 3 Class Design Actions: what task? Verbs and verb-phrases Associate actions with key objects Who does the "doing"? Information: what data? Attributes for object state Parameters for method information
13

L05 Designing Classes

May 13, 2017

Download

Documents

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: L05 Designing Classes

Computer Programming 2Paul Calder

Designing ClassesClass: A blueprint for creating objects

Flinders University / Computer Programming 2 2

Program Design•Look for the objects•Think "objects interacting"•Nouns and noun phrases

•Decide on the classes•Similar kinds of objects•Category nouns• "Is-a" relationships

Flinders University / Computer Programming 2 3

Class Design•Actions: what task?•Verbs and verb-phrases•Associate actions with key objects•Who does the "doing"?

•Information: what data?•Attributes for object state•Parameters for method information

Page 2: L05 Designing Classes

Flinders University / Computer Programming 2 4

Class Structure•Scope•Of a declaration: variable, method, class•Where should this be visible? Who needs to use this?

•Visibility•Locals & parameters - just that method call•Private - any method of that class•Public - anyone

Flinders University / Computer Programming 2 5

Thin Interfaces•Minimise public•Easier to understand: "need-to-know"•Easier to change: "information hiding"

•Minimise attributes•Locals for temporary values•Parameters to provide call-specific information•Attributes only if no other mechanism possible!

•Accessors•Controlled access to attributes (instance state)

Flinders University / Computer Programming 2

Function-Revealing Names•Names tell the story•Real words, not (gratuitous) abbreviations•Length: fit for purpose (related to size of scope)

•Correct part of speech•Nouns: variables, params, value-return functions (length(), valueAt(...))•Verbs: void methods (expand(), rotateRight())

•Special case conventions•Predicates: "tobe" phrase (isOpen, willSucceed, hasErrors)•Accessors: get/set convention (getName, setAge)• Idioms: i, j, k for (integer) loops; n, m, p, q for "maths" variables

6

Beware of l, o

•CamelCase for multiword•Classes start with upper•Others start with lower

small scope: short namelarge scope: longer name

Page 3: L05 Designing Classes

Flinders University / Computer Programming 2

#ifndef THING_H#define THING_H

class Thing {public: Thing(); Thing(int initialValue);

void doSomething(int withThisData); int tellMeSomething();

void setAnotherValue(double); double getAnotherValue();

private: int aValue_; double andAnother_;};

#endif

Class Interface

7

If not (yet) defined...

... then define it so it won't be redefined if included again

Constructors

Operational methods

Accessor methods

Instance variables

Flinders University / Computer Programming 2

#include "Thing.h"

Thing::Thing() { ... }

Thing::Thing(int initialValue) { ... }

void Thing::doSomething(int withThisData) { ... }

int Thing::tellMeSomething() { ... return ...; }

void Thing::setAnotherValue(double v) { andAnother_ = v; }

double Thing::getAnotherValue() { return andAnother_; }

Class Implementation

8

Include the class header

Scope specifier

Flinders University / Computer Programming 2 9

Accessor Methods•Access to state•Clients need to know•But supplies need to maintain control

•Solution•Make attribute variable private•Public "get" method if read needed•Public "set" method if write needed

Page 4: L05 Designing Classes

Flinders University / Computer Programming 2

class ... {

..

private: Type attribute_;

public: Type getAttribute() const { return attribute_; }

void setAttribute(Type value) { // safety checks here attribute_ = value; }

...

};

10

Accessor Proformaconst method can be called on an unchangeable object

Flinders University / Computer Programming 2

class Person {

private: int age_;

public: int getAge() const { return age_; }

void setAge(int age) { if (age >= 0 && age_ <= 120) { age_ = age; } }

};

11

Accessor Example

Sanity checking to ensure attribute values are sensible.

Flinders University / Computer Programming 2

class Controller {public: Rectangle re; int x; int x1; int x2; int s; int x3; int x4; int s1;

Controller(Rectangle r);

void mover(int s); void changer(int m);};

Controller::Controller(Rectangle r) { re = r;}

void Controller::mover(int s) { x = re.getX(); x2 = re.getY(); x1 = x + s; re.setPosition(x1, x2);}

void Controller::changer(int m) { s = re.getHeight(); x3 = re.getX() + s/2; x4 = re.getY() + s/2; s1 = s - m; re.setSize(s1, s1); re.setPosition(x3 - s1/2, x4 - s1/2);}

Improve this class

12

class Rect

angle {

public:

Rectangl

e();

int getH

eight() co

nst;

int getW

idth() con

st;

int getX

() const;

int getY

() const;

void set

Position(i

nt x, int

y);

void set

Size(int w

, int h);

};

This code breaks manyrules of style!

Page 5: L05 Designing Classes

Flinders University / Computer Programming 2

class TargetController {public: TargetController(Rectangle);

void moveUp(int step); void shrink(int step);

void setTarget(Rectangle); Rectangle getTarget() const;private: Rectangle target_;};

TargetController::TargetController(Rectangle target) { target_ = target;}

void TargetController::moveUp(int step) { int x = target_.getX(); int y = target_.getY(); x += step; target_.setPosition(x, y);}

void TargetController::shrink(int step) { ing size = target_.getHeight(); int midX = target_.getX() + size/2; int midY = target_.getY() + size/2; size -= step; target_.setSize(size, size); target_.setPosition(midX - size/2, midY - size/2);}

void TargetController:: setTarget(Rectangle target) { target_ = target;}

Rectangle TargetController::getTarget() const { return target_;}

Much better!

13

✓Temporary variables local

✓Names reveal functions

✓Instance variable names

✓Accessor methods

✓Private instance variables

Computer Programming 2Paul Calder

A Design ExampleA class for counting in circles

Flinders University / Computer Programming 2

int main() {

// What’s 6 months after October? Counter month(1, 12); month.setCount(10); month.step(6); cout << month.getCount() << endl;

// If I start at 5pm and work for 20 hours straight, what time would I finish?Counter hour(0, 23);hour.setCount(17);hour.step(20);cout << hour.getCount() << endl;

}

15

Counting in Circles

Page 6: L05 Designing Classes

Flinders University / Computer Programming 2 16

Counter Design•Thin interface•Constructor: count limits•Operational: step by n with wrap around•Accessor: controlled read and write access

•Minimise visibility•Choose local before private before public•Minimise public interface

•Function-revealing names•Methods, variables, parameters

Flinders University / Computer Programming 2

class Counter {public: Counter( int count = 0, int lowest_ = 0, int highest_ = INT_MAX );

void step(int size = 1); int getCount() const; void setCount(int count);

private: int count_; int lowest_; int highest_;};

Counter::Counter(int count, int lowest, int highest) { lowest_ = min(lowest, highest); highest_ = max(lowest, highest); setCount(count);}

void Counter::step(int size) { // simple but inefficient! while (size > 0) { count_ += 1; if (count_ > highest_) count_ = lowest_; } while (size < 0) { count_ -= 1; if (count_ < lowest_) count_ = highest_; }}

int Counter::getCount() const { return count_;}

void Counter::setCount(int count) { count = count; count_ = min(count_, highest_); count_ = max(count_, lowest_);}

17

Basic Counter

Flinders University / Computer Programming 2

class Counter {public: ... Counter(const Counter&);

Counter& operator =(const Counter&); Counter& operator =(int);

operator int() const;

Counter& operator +=(int step); Counter& operator -=(int step);

Counter operator +(int step); Counter operator -(int step);

friend std::istream& operator >>(std::istream&, Counter&); friend std::ostream& operator <<(std::ostream&, const Counter&); ...}

18

Add OperatorsCopy constructor

Assignment operators

Conversion operator

Counter

c1(2, 0, 9

9);

Counter

c2(c1);

Counter

c3;

c2 = 10;

c3 = c1;

c1 -= 3;

c2 = c1

+ 4;

c3 = c1

+ c2;

cout <<

"Counter:

";

cin >> c

1;

cout <<

c1 << endl

;friend: an ordinary function with privileged access

Page 7: L05 Designing Classes

Flinders University / Computer Programming 2

Counter::Counter(const Counter& other) { count_ = other.count_; lowest_ = other.lowest_; highest_ = other.highest_;}

Counter& Counter::operator =(const Counter& other) { count_ = other.count_; lowest_ = other.lowest_; highest_ = other.highest_; return *this;}

Counter& Counter::operator =(int other) { setCount(other); return *this;}

Counter::operator int() const { return getCount();}

19

Constructors & assignment

assignment operators return values!

Flinders University / Computer Programming 2

Counter& Counter::operator +=(int step) { step(step); return *this;}

Counter& Counter::operator -=(int step) { step(-step); return *this;}

Counter Counter::operator +(int step) { Counter result(*this); result += step; return result;}

Counter Counter::operator -(int step) { Counter result(*this); result -= step; return result;}

20

Arithmetic operators

Flinders University / Computer Programming 2

std::istream& operator >>(std::istream& in, Counter& c) { char d1, d2, d3, d4; int count, min, max; if (in >> d1 >> count >> d2 >> min >> d3 >> max >> d4) { if (d1 == '(' && d2 == ',' && d3 == ',' && d4 == ')') { c = Counter(max, min); c.setCount(count); } else { in.setstate(in.failbit); } } return in;}

std::ostream& operator <<(std::ostream& out, const Counter& c) { out << "(" << c.count_ << "," << c.min_ << "," << c.max_ << ")"; return out;}

21

IO operators

( 3, -10,

10 )

A counter for the range -10 .. +10, with

current value 3.

a friend function: no scope operator

Page 8: L05 Designing Classes

Flinders University / Computer Programming 2

int main() { Counter c1, c2, c3;

cin >> c1; cin >> c2;

c1 = 15; c3 = c1 + c2; c2 += c1.getCount();

cout << c1 << c2 << c3 << endl; }

22

Try it out

Computer Programming 2Paul Calder

Design ExerciseTimes Square text

Flinders University / Computer Programming 2

int main() { TimesSquare message("Hello, world!"); for (int i = 1; i <= message.length(); i++) { cout << message.getText() << endl; message.rotateLeft(); }}

TimesSquare

24

Write a program that implements "TimesSquare" text.

Hello, world!ello, world!Hllo, world!Helo, world!Helo, world!Hell, world!Hello world!Hello,world!Hello,

orld!Hello, wrld!Hello, wold!Hello, word!Hello, worl!Hello, world

Page 9: L05 Designing Classes

Flinders University / Computer Programming 2

#include <string>

class TimesSquare {public: TimesSquare(std::string text);

void rotateLeft(); int length() const; std::string getText() const;

private: std::string text_;};

Basic class definition

25

Shouldn't put using namespace statement into header files, because users do not want to be locked

in. Therefore need fully specified names.

Flinders University / Computer Programming 2

TimesSquare::TimesSquare(string s) { text_ = s;}

int TimesSquare::length() const { return text_.length();}

string TimesSquare::getText() const { return text_;}

void TimesSquare::setText(string s) { text_ = s;}

void TimesSquare::rotateLeft() { text_.insert(text_.length, 1, text_[0]); text_.erase(0, 1);}

Basic class implementation

26

Download

TimesS

quare_

0.zip

Flinders University / Computer Programming 2

class TimesSquare {public:TimesSquare(const TimesSquare& other);

TimesSquare(string text = "");

TimesSquare& operator =(const TimesSquare& other);

void rotateLeft(int steps = 1); void rotateRight(int steps = 1);

int length() const;

string getText() const; void setText(string s);

private: string text_;};

Completing the class

27

copy constructor

assignment operator

default parameters

full set of methods

Page 10: L05 Designing Classes

Flinders University / Computer Programming 2

void TimesSquare::rotateRight(int steps) { int length = text_.length(); if (length > 0) { for (int i = 0; i < steps; i++) { text_.insert(0, 1, text_[length - 1]); text_.erase(length, 1); // briefly one character longer } }}

void TimesSquare::rotateLeft(int steps) { int length = text_.length(); if (length > 0) { for (int i = 0; i < steps; i++) { text_.insert(length, 1, text_[0]); text_.erase(0, 1); } }}

Rotate methods

28

Flinders University / Computer Programming 2

class TimesSquare {public: ...

TimesSquare& operator <<=(int shift); TimesSquare& operator >>=(int shift);

friend TimesSquare operator <<(TimesSquare t, int shift) { return t <<= shift; } friend TimesSquare operator >>(TimesSquare t, int shift) { return t >>= shift; }

friend ostream& operator <<(ostream&, const TimesSquare&); friend istream& operator >>(istream&, TimesSquare&);

...};

Operators

29

Is this a

good use of

operator

overloading??

Flinders University / Computer Programming 2

TimesSquare& TimesSquare::operator <<=(int shift) { rotateLeft(shift); return *this;}

TimesSquare& TimesSquare::operator >>=(int shift) { rotateRight(shift); return *this;}

ostream& operator <<(ostream& out, const TimesSquare& from) { return out << from.text_;}

istream& operator >>(istream& in, TimesSquare& to) { return getline(in, to.text_);}

Implementing operators

30

Page 11: L05 Designing Classes

Flinders University / Computer Programming 2

int main() { TimesSquare message("");

cout << "Message: "; cin >> message; for (int i = 1; i <= message.length(); i++) { cout << (message << i) << endl;

} for (int i = 1; i <= message.length(); i += 2) { cout << (message >>= 2) << endl; }

cout << (message << 3 >> 5);}

Using the operators

31

What does this mean?

What if the () were missing?

Computer Programming 2Paul Calder

SafeArrayNow that you've done the homework...

Flinders University / Computer Programming 2

template <T>class SafeArray {public: SafeArray(int length); SafeArray& operator =(const SafeArray& other);

bool operator ==(const SafeArray& other) const; bool operator !=(const SafeArray& other) const;

int length() const; T& operator [](int index);private: int length_; T elements_[100];};

Template class

33

The C++ template mechanism allows a class definition to be parameterised by a type. Define a template version of the class with the type of the array elements as a parameter.

SafeArra

y<int> ai(

10);

SafeArra

y<string>

as(20);

ai[3] =

42;

as[15] =

"Hello";

Page 12: L05 Designing Classes

Flinders University / Computer Programming 2

template <T>class SafeArray {public: SafeArray(int length); SafeArray& operator =(const SafeArray& other);

bool operator ==(const SafeArray& other) const; bool operator !=(const SafeArray& other) const;

int length() const; T& operator [](int index);private: int length_; T elements_[100];};

Template class

34

The C++ template mechanism allows a class definition to be parameterised by a type. Define a template version of the class with the type of the array elements as a parameter.

SafeArra

y<int> ai(

10);

SafeArra

y<string>

as(20);

ai[3] =

42;

as[15] =

"Hello";

Flinders University / Computer Programming 2

// simple out-of-bounds processingT& SafeArray::operator [](int index) { if (index < 0) return elements_[0]; if (index >= length_) return elements_[length_ - 1]; return elements_[index];}

Out-of-bounds Indexing

35

Consider alternate strategies for dealing with array indexes that fall outside the valid range. What are the merits and

shortcomings of each approach?

SafeArra

y<int> a(2

);

a[0] = 0

;

a[1] = 1

;

a[2] = 2

; // oops

!

cout <<

a[0] << a[

1] << endl

;

Flinders University / Computer Programming 2

// wrap-around out-of-bounds processingT& SafeArray::operator [](int index) { return elements_[index_ % length_];}

// throw exception for out-of-bound indexT& SafeArray::operator [](int index) { if (index < 0 || index >= length_) { string message = "SafeArray index out of range"; throw out_of_range(message); } return elements_[index];

}

Out-of-bounds Indexing

36

Consider alternate strategies for dealing with array indexes that fall outside the valid range. What are the merits and

shortcomings of each approach?

SafeArra

y<int> a(2

);

a[0] = 0

;

a[1] = 1

;

a[2] = 2

; // oops

!

cout <<

a[0] << a[

1] << endl

;

Page 13: L05 Designing Classes

Flinders University / Computer Programming 2

class SafeArray {public: SafeArray(int length); ...private: int length_; int elements_[100];};

Variable-sized array

37

The current class stores the elements in a fixed-size array. What are the consequences of this implementation decision?

How could you overcome those limitations?

SafeArra

y<int> x(1

0); /

/ OK

SafeArra

y<string>

y(100); /

/ just OK

SafeArra

y<float> z

(1000); /

/ OOPS!

Flinders University / Computer Programming 2

class SafeArray {public: SafeArray(int length); ...private: int length_; T* elements_;};

SafeArray::SafeArray(int length) { length_ = length; elements = new T[length_];}

SafeArray::~SafeArray() { delete[] elements_;}

Variable-sized array

38

The current class stores the elements in a fixed-size array. What are the consequences of this implementation decision?

How could you overcome those limitations?

static array

5length_

elements_ 0 1 2 98 99...3 4 5 6 7

dynamic array

5length_

elements_0 1 2 3 4