L05 Designing Classes

13
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

Transcript of 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

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

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

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!

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

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

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

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

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

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

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";

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

;

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