toward a common intuition and reusable testing methodology€¦ · 1. the .cpp file includes its .h...

470
1 Proper Inheritance John Lakos Tuesday, May 10, 2016

Upload: others

Post on 07-Aug-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1

Proper Inheritance

John Lakos

Tuesday, May 10, 2016

Page 2: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

2

Copyright Notice

© 2016 Bloomberg L.P. Permission is granted to copy, distribute, and display this material, and to make derivative works and commercial use of it. The information in this material is provided "AS IS", without warranty of any kind. Neither Bloomberg nor any employee guarantees the correctness or completeness of such information. Bloomberg, its employees, and its affiliated entities and persons shall not be liable, directly or indirectly, in any way, for any inaccuracies, errors or omissions in such information. Nothing herein should be interpreted as stating the opinions, policies, recommendations, or positions of Bloomberg.

Page 3: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

3

Abstract All essential behavior of our software must be documented, and yet there are

important advantages, with respect to development, verification and testing,

performance, and stability, for leaving the behavior for some combinations of

inputs and initial conditions undefined. What is and is not defined behavior

should therefore be readily discernible from the contract, especially when

creating contracts that must span classes related by inheritance.

In this two-part talk, we begin by reviewing components, interfaces and

contracts in general, and the significance of narrow versus wide contracts. In

the second part, we go on to explore three kinds of inheritance: (1) Interface

Inheritance resulting from pure-virtual functions, (2) Structural Inheritance

resulting from non-virtual functions, and (3) Implementation Inheritance

resulting from non-pure virtual functions. Proper contracts involving each of

these distinct forms have different criteria that must be addressed. The three

kinds of inheritance are compared, and their relative utility is explained.

What's more, several common uses of inheritance that are provably improper

are summarily debunked.

Page 4: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4

What’s The Problem?

Page 5: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

5

What’s The Problem? Large-Scale C++ Software Design is Multi-Dimensional:

Page 6: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

6

What’s The Problem? Large-Scale C++ Software Design is Multi-Dimensional:

• It involves many subtle logical and physical aspects.

Page 7: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

7

What’s The Problem? Large-Scale C++ Software Design is Multi-Dimensional:

• It involves many subtle logical and physical aspects.

• It requires an ability to isolate and modularize logical functionality within discrete, fine-grain physical components.

Page 8: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

8

What’s The Problem? Large-Scale C++ Software Design is Multi-Dimensional:

• It involves many subtle logical and physical aspects.

• It requires an ability to isolate and modularize logical functionality within discrete, fine-grain physical components.

• It requires the designer to delineate logical behavior precisely, while managing the physical dependencies on other subordinate components.

Page 9: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

9

What’s The Problem? Large-Scale C++ Software Design is Multi-Dimensional:

• It involves many subtle logical and physical aspects.

• It requires an ability to isolate and modularize logical functionality within discrete, fine-grain physical components.

• It requires the designer to delineate logical behavior precisely, while managing the physical dependencies on other subordinate components.

• It requires attention to numerous logical and physical rules that govern sound software design.

Page 10: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

10

Purpose of this Talk

Page 11: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

11

Purpose of this Talk

Review:

Page 12: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

12

Purpose of this Talk

Review: 1. Components – Our fundamental unit of logical and physical design

Page 13: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

13

Purpose of this Talk

Review: 1. Components – Our fundamental unit of logical and physical design

2. Interfaces and contracts (in general)

Page 14: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

14

Purpose of this Talk

Review: 1. Components – Our fundamental unit of logical and physical design

2. Interfaces and contracts (in general)

3. Narrow versus Wide contracts (in particular)

Page 15: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

15

Purpose of this Talk

Review: 1. Components – Our fundamental unit of logical and physical design

2. Interfaces and contracts (in general)

3. Narrow versus Wide contracts (in particular)

4. Explore these basic ideas in the context inheritance.

Page 16: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

16

Outline

1. Components (review)

Modularity, Logical/Physical Dependencies, & Level numbers

2. Interfaces and Contracts (review)

Syntax versus Semantics & Essential Behavior

3. Narrow versus Wide Contracts (review)

The Significance of Undefined Behavior

4. Proper Inheritance Is-A for Interface, Structural, & Implementation Inheritance

Page 17: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

17

Outline

1. Components (review)

Modularity, Logical/Physical Dependencies, & Level numbers

2. Interfaces and Contracts (review)

Syntax versus Semantics & Essential Behavior

3. Narrow versus Wide Contracts (review)

The Significance of Undefined Behavior

4. Proper Inheritance Is-A for Interface, Structural, & Implementation Inheritance

Page 18: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Logical versus Physical Design

What distinguishes Logical from Physical Design?

Logical

physical

18

Page 19: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Logical versus Physical Design

What distinguishes Logical from Physical Design? Logical: Classes and Functions

Logical

physical

19

Page 20: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Logical versus Physical Design

What distinguishes Logical from Physical Design? Logical: Classes and Functions Physical: Files and Libraries

Logical

physical

20

Page 21: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Logical versus Physical Design

Logical content aggregated into a Physical hierarchy of components

a b

c

21

Page 22: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Component: Uniform Physical Structure

// component.t.cpp

#include <component.h>

// ...

int main(...)

{

//...

}

//-- END OF FILE --

component.t.cpp

// component.h

// ...

//-- END OF FILE --

// component.cpp

#include <component.h>

// ...

//-- END OF FILE --

component.h component.cpp

component

A Component Is Physical

22

Page 23: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Component: Uniform Physical Structure

// component.t.cpp

#include <component.h>

// ...

int main(...)

{

//...

}

//-- END OF FILE --

component.t.cpp

// component.h

// ...

//-- END OF FILE --

// component.cpp

#include <component.h>

// ...

//-- END OF FILE --

component.h component.cpp

component

Implementation

23

Page 24: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Component: Uniform Physical Structure

// component.t.cpp

#include <component.h>

// ...

int main(...)

{

//...

}

//-- END OF FILE --

component.t.cpp

// component.h

// ...

//-- END OF FILE --

// component.cpp

#include <component.h>

// ...

//-- END OF FILE --

component.h component.cpp

component

Header

24

Page 25: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Component: Uniform Physical Structure

// component.t.cpp

#include <component.h>

// ...

int main(...)

{

//...

}

//-- END OF FILE --

component.t.cpp

// component.h

// ...

//-- END OF FILE --

// component.cpp

#include <component.h>

// ...

//-- END OF FILE --

component.h component.cpp

component

Test Driver

25

Page 26: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Component: Uniform Physical Structure

// component.t.cpp

#include <component.h>

// ...

int main(...)

{

//...

}

//-- END OF FILE --

component.t.cpp

// component.h

// ...

//-- END OF FILE --

// component.cpp

#include <component.h>

// ...

//-- END OF FILE --

component.h component.cpp

component

The Fundamental Unit of Design

26

Page 27: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Component: Not Just a .h/.cpp Pair

my::Widget

my_widget

27

Page 28: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

28

1. Components (review)

Component: Not Just a .h/.cpp Pair

Page 29: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. The .cpp file includes its .h file as the first substantive line of code.

29

1. Components (review)

Component: Not Just a .h/.cpp Pair

Page 30: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. The .cpp file includes its .h file as the first substantive line of code.

2. All logical constructs having external linkage defined in a .cpp file are declared in the corresponding .h file.

3. All constructs having external or dual bindage declared in a .h file (if defined at all) are defined within the component.

4. A component’s functionality is accessed via a #include of its header, and never via a forward (extern) declaration.

30

1. Components (review)

Component: Not Just a .h/.cpp Pair

Page 31: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. The .cpp file includes its .h file as the first substantive line of code.

2. All logical constructs having external linkage defined in a .cpp file are declared in the corresponding .h file.

3. All constructs having external or dual bindage declared in a .h file (if defined at all) are defined within the component.

4. A component’s functionality is accessed via a #include of its header, and never via a forward (extern) declaration.

31

1. Components (review)

Component: Not Just a .h/.cpp Pair

We could easily spend 20 minutes on this slide alone!

Page 32: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. The .cpp file includes its .h file as the first substantive line of code.

2. All logical constructs having external linkage defined in a .cpp file are declared in the corresponding .h file.

3. All constructs having external or dual bindage declared in a .h file (if defined at all) are defined within the component.

4. A component’s functionality is accessed via a #include of its header, and never via a forward (extern) declaration.

32

1. Components (review)

Component: Not Just a .h/.cpp Pair Achieve

Logical/Physical Modularity

Avoid Global Namespace

Pollution

Enable Efficient Extraction of

Physical Dependencies

Page 33: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. The .cpp file includes its .h file as the first substantive line of code.

2. All logical constructs having external linkage defined in a .cpp file are declared in the corresponding .h file.

3. All constructs having external or dual bindage declared in a .h file (if defined at all) are defined within the component.

4. A component’s functionality is accessed via a #include of its header, and never via a forward (extern) declaration.

33

1. Components (review)

Component: Not Just a .h/.cpp Pair Achieve

Logical/Physical Modularity

Avoid Global Namespace

Pollution

Enable Efficient Extraction of

Physical Dependencies

For much more see

ADVANCED LEVELIZATION TECHNIQUES

Page 34: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Logical Relationships

Shape

PointList

PointList_Link

Polygon

Point

34

Underscore Implies Component-Local Class

Page 35: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Logical Relationships

Shape

PointList

PointList_Link

Is-A

Polygon

Point

35

Page 36: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Logical Relationships

Shape

PointList

PointList_Link

Is-A

Polygon

Point

36

Page 37: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Logical Relationships

Shape

PointList

PointList_Link

Is-A

Uses-in-the-Interface

Polygon

Point

37

Page 38: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Logical Relationships

Shape

PointList

PointList_Link

Is-A

Uses-in-the-Interface

Polygon

Point

38

Page 39: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Logical Relationships

Shape

PointList

PointList_Link

Is-A

Uses-in-the-Interface

Polygon

Point

39

Page 40: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Logical Relationships

Shape

PointList

PointList_Link

Is-A Uses-in-the-Implementation

Uses-in-the-Interface

Polygon

Point

40

Page 41: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Logical Relationships

Shape

PointList

PointList_Link

Is-A Uses-in-the-Implementation

Uses-in-the-Interface

Polygon

Point

41

Page 42: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Logical Relationships

Shape

PointList

PointList_Link

Is-A Uses-in-the-Implementation

Uses-in-the-Interface

Polygon

Point

42

Page 43: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Logical Relationships

Shape

PointList

PointList_Link

Is-A Uses-in-the-Implementation

Uses-in-the-Interface Uses in name only

Polygon

Point

43

Page 44: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Logical Relationships

Shape

PointList

PointList_Link

Is-A Uses-in-the-Implementation

Uses-in-the-Interface Uses in name only

Polygon

Point

44

Page 45: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Implied Dependency

Shape

PointList

PointList_Link

Is-A Uses-in-the-Implementation

Uses-in-the-Interface Uses in name only

Polygon

Point

45

Page 46: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Implied Dependency

Shape

PointList

PointList_Link

Is-A Uses-in-the-Implementation

Uses-in-the-Interface Uses in name only

Depends-On

Polygon

Point

46

Page 47: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Implied Dependency

Shape

PointList

PointList_Link

Is-A Uses-in-the-Implementation

Uses-in-the-Interface Uses in name only

Depends-On

Polygon

Point

47

Page 48: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Implied Dependency

Shape

PointList

PointList_Link

Is-A Uses-in-the-Implementation

Uses-in-the-Interface Uses in name only

Depends-On

Polygon

Point

48

Page 49: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Implied Dependency

Shape

PointList

PointList_Link

Is-A Uses-in-the-Implementation

Uses-in-the-Interface Uses in name only

Depends-On

Polygon

Point

49

Page 50: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Implied Dependency

Shape

PointList

PointList_Link

Is-A Uses-in-the-Implementation

Uses-in-the-Interface Uses in name only

Depends-On

Polygon

Point

50

Page 51: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Level Numbers

Shape

PointList

PointList_Link

Is-A Uses-in-the-Implementation

Uses-in-the-Interface Uses in name only

Depends-On

Polygon

Point

51

Page 52: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Level Numbers

Shape

PointList

PointList_Link

Is-A Uses-in-the-Implementation

Uses-in-the-Interface

1

Uses in name only

Depends-On

Polygon

Point

52

Page 53: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Level Numbers

Shape

PointList

PointList_Link

Is-A Uses-in-the-Implementation

Uses-in-the-Interface

1 1

Uses in name only

Depends-On

Polygon

Point

53

Page 54: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Level Numbers

Shape

PointList

PointList_Link

Is-A Uses-in-the-Implementation

Uses-in-the-Interface

1 1

2

Uses in name only

Depends-On

Polygon

Point

54

Page 55: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Level Numbers

Shape

PointList

PointList_Link

Is-A Uses-in-the-Implementation

Uses-in-the-Interface

1 1

2 3

Uses in name only

Depends-On

Polygon

Point

55

Page 56: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Essential Physical Design Rules

56

Page 57: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Essential Physical Design Rules

There are two:

57

Page 58: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Essential Physical Design Rules

There are two:

1.No Cyclic Physical Dependencies!

58

Page 59: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

Essential Physical Design Rules

There are two:

1.No Cyclic Physical Dependencies!

2.No Long-Distance Friendships!

59

Page 60: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

End of Section

Questions?

Page 61: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

1. Components (review)

What Questions are we Answering? • What distinguishes Logical and Physical Design? • What is the first of the (four) fundamental properties of

a .h /.cpp pair that make it a component? • Which of these fundamental properties helps us extract

physical dependencies efficiently? Extra credit: Why? How? • What are the (four) logical-relationship annotations? • Which logical relationship does not imply a physical one? • How do we infer physical relationships (Depends-On)

from logical ones? • What do we mean by the term level number? • What are the (two) quintessential physical design rules?

61

Page 62: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

62

Outline

1. Components (review)

Modularity, Logical/Physical Dependencies, & Level numbers

2. Interfaces and Contracts (review)

Syntax versus Semantics & Essential Behavior

3. Narrow versus Wide Contracts (review)

The Significance of Undefined Behavior

4. Proper Inheritance Is-A for Interface, Structural, & Implementation Inheritance

Page 63: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

63

Outline

1. Components (review)

Modularity, Logical/Physical Dependencies, & Level numbers

2. Interfaces and Contracts (review)

Syntax versus Semantics & Essential Behavior

3. Narrow versus Wide Contracts (review)

The Significance of Undefined Behavior

4. Proper Inheritance Is-A for Interface, Structural, & Implementation Inheritance

Page 64: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

64

2. Interfaces and Contracts (review)

Interfaces and Contracts

What do we mean by Interface versus Contract for

• A Function? • A Class? • A Component?

Page 65: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

65

2. Interfaces and Contracts (review)

Interfaces and Contracts

Function std::ostream& print(std::ostream& stream,

int level = 0,

int spacesPerLevel = 4) const;

Page 66: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

66

2. Interfaces and Contracts (review)

Interfaces and Contracts

Function std::ostream& print(std::ostream& stream,

int level = 0,

int spacesPerLevel = 4) const;

Types Used

In the Interface

Page 67: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

67

2. Interfaces and Contracts (review)

Interfaces and Contracts

Function std::ostream& print(std::ostream& stream,

int level = 0,

int spacesPerLevel = 4) const; // Format this object to the specified output 'stream' at the (absolute

// value of) the optionally specified indentation 'level' and return a

// reference to 'stream'. If 'level' is specified, optionally specify

// 'spacesPerLevel', the number of spaces per indentation level for

// this and all of its nested objects. If 'level' is negative,

// suppress indentation of the first line. If 'spacesPerLevel' is

// negative, format the entire output on one line, suppressing all but

// the initial indentation (as governed by 'level'). If 'stream' is

// not valid on entry, this operation has no effect.

Page 68: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

68

2. Interfaces and Contracts (review)

Interfaces and Contracts

Class class Date { // This class implements a value-semantic type representing // a valid date in history between the dates 0001/01/01 and // 9999/12/31 inclusive.

//…

public:

Date(int year, int month, int day); // Create a valid date from the specified ‘year’, ‘month’, and // ‘day’. The behavior is undefined unless ‘year’/’month’/’day’ // represents a valid date in the range [0001/01/01 .. 9999/12/31].

Date(const Date& original); // Create a date having the value of the specified ‘original’ date.

// …

};

Page 69: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

69

2. Interfaces and Contracts (review)

Interfaces and Contracts

Class class Date { // This class implements a value-semantic type representing // a valid date in history between the dates 0001/01/01 and // 9999/12/31 inclusive.

//…

public:

Date(int year, int month, int day); // Create a valid date from the specified ‘year’, ‘month’, and // ‘day’. The behavior is undefined unless ‘year’/’month’/’day’ // represents a valid date in the range [0001/01/01 .. 9999/12/31].

Date(const Date& original); // Create a date having the value of the specified ‘original’ date.

// …

};

Public

Interface

Page 70: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

70

2. Interfaces and Contracts (review)

Interfaces and Contracts

Class class Date { // This class implements a value-semantic type representing // a valid date in history between the dates 0001/01/01 and // 9999/12/31 inclusive.

//…

public:

Date(int year, int month, int day); // Create a valid date from the specified ‘year’, ‘month’, and // ‘day’. The behavior is undefined unless ‘year’/’month’/’day’ // represents a valid date in the range [0001/01/01 .. 9999/12/31].

Date(const Date& original); // Create a date having the value of the specified ‘original’ date.

// …

};

Page 71: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

71

2. Interfaces and Contracts (review)

Interfaces and Contracts

Class class Date { // This class implements a value-semantic type representing // a valid date in history between the dates 0001/01/01 and // 9999/12/31 inclusive.

//…

public:

Date(int year, int month, int day); // Create a valid date from the specified ‘year’, ‘month’, and // ‘day’. The behavior is undefined unless ‘year’/’month’/’day’ // represents a valid date in the range [0001/01/01 .. 9999/12/31].

Date(const Date& original); // Create a date having the value of the specified ‘original’ date.

// …

};

Page 72: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

72

2. Interfaces and Contracts (review)

Interfaces and Contracts

Class class Date { // This class implements a value-semantic type representing // a valid date in history between the dates 0001/01/01 and // 9999/12/31 inclusive.

//…

public:

Date(int year, int month, int day); // Create a valid date from the specified ‘year’, ‘month’, and // ‘day’. The behavior is undefined unless ‘year’/’month’/’day’ // represents a valid date in the range [0001/01/01 .. 9999/12/31].

Date(const Date& original); // Create a date having the value of the specified ‘original’ date.

// …

};

Page 73: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

73

2. Interfaces and Contracts (review)

Interfaces and Contracts

Class class Date { // This class implements a value-semantic type representing // a valid date in history between the dates 0001/01/01 and // 9999/12/31 inclusive.

//…

public:

Date(int year, int month, int day); // Create a valid date from the specified ‘year’, ‘month’, and // ‘day’. The behavior is undefined unless ‘year’/’month’/’day’ // represents a valid date in the range [0001/01/01 .. 9999/12/31].

Date(const Date& original); // Create a date having the value of the specified ‘original’ date.

// …

};

Page 74: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

74

2. Interfaces and Contracts (review)

Interfaces and Contracts

Component

class Date { // … public: // … };

bool operator==(const Date& lhs, const Date& rhs); // Return ‘true’ if the specified ‘lhs’ and ‘rhs’ dates have the same // value, ‘and’ false otherwise. Two ‘Date’ objects have the same // value if their respective ‘year’, ‘month’, and ‘day’ attributes // have the same value. bool operator!=(const Date& lhs, const Date& rhs); // Return ‘true’ if the specified ‘lhs’ and ‘rhs’ dates no not have the // same value and false otherwise. Two ‘Date’ objects do not have // the same value if any of their respective ‘year’, ‘month’, and ‘day’ // attributes do not have the same value. std::ostream& operator<<(std::ostream& stream, const Date& date); // Format the value of the specified ‘date’ object to the specified // output ‘stream’ as ‘yyyy/mm/dd’.

Page 75: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

75

2. Interfaces and Contracts (review)

Interfaces and Contracts

Component

class Date { // … public: // … };

bool operator==(const Date& lhs, const Date& rhs); // Return ‘true’ if the specified ‘lhs’ and ‘rhs’ dates have the same // value, ‘and’ false otherwise. Two ‘Date’ objects have the same // value if their respective ‘year’, ‘month’, and ‘day’ attributes // have the same value. bool operator!=(const Date& lhs, const Date& rhs); // Return ‘true’ if the specified ‘lhs’ and ‘rhs’ dates no not have the // same value and false otherwise. Two ‘Date’ objects do not have // the same value if any of their respective ‘year’, ‘month’, and ‘day’ // attributes do not have the same value. std::ostream& operator<<(std::ostream& stream, const Date& date); // Format the value of the specified ‘date’ object to the specified // output ‘stream’ as ‘yyyy/mm/dd’.

“Public”

Interface

Page 76: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

76

2. Interfaces and Contracts (review)

Interfaces and Contracts

Component

class Date { // … public: // … };

bool operator==(const Date& lhs, const Date& rhs); // Return ‘true’ if the specified ‘lhs’ and ‘rhs’ dates have the same // value, ‘and’ false otherwise. Two ‘Date’ objects have the same // value if their respective ‘year’, ‘month’, and ‘day’ attributes // have the same value. bool operator!=(const Date& lhs, const Date& rhs); // Return ‘true’ if the specified ‘lhs’ and ‘rhs’ dates no not have the // same value and false otherwise. Two ‘Date’ objects do not have // the same value if any of their respective ‘year’, ‘month’, and ‘day’ // attributes do not have the same value. std::ostream& operator<<(std::ostream& stream, const Date& date); // Format the value of the specified ‘date’ object to the specified // output ‘stream’ as ‘yyyy/mm/dd’.

Page 77: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

77

2. Interfaces and Contracts (review)

Interfaces and Contracts

Component

class Date { // … public: // … };

bool operator==(const Date& lhs, const Date& rhs); // Return ‘true’ if the specified ‘lhs’ and ‘rhs’ dates have the same // value, and ‘false’ otherwise. Two ‘Date’ objects have the same // value if their respective ‘year’, ‘month’, and ‘day’ attributes // have the same value. bool operator!=(const Date& lhs, const Date& rhs); // Return ‘true’ if the specified ‘lhs’ and ‘rhs’ dates no not have the // same value and false otherwise. Two ‘Date’ objects do not have // the same value if any of their respective ‘year’, ‘month’, and ‘day’ // attributes do not have the same value. std::ostream& operator<<(std::ostream& stream, const Date& date); // Format the value of the specified ‘date’ object to the specified // output ‘stream’ as ‘yyyy/mm/dd’.

Page 78: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

78

2. Interfaces and Contracts (review)

Interfaces and Contracts

Component

class Date { // … public: // … };

bool operator==(const Date& lhs, const Date& rhs); // Return ‘true’ if the specified ‘lhs’ and ‘rhs’ dates have the same // value, and ‘false’ otherwise. Two ‘Date’ objects have the same // value if their respective ‘year’, ‘month’, and ‘day’ attributes // have the same value. bool operator!=(const Date& lhs, const Date& rhs); // Return ‘true’ if the specified ‘lhs’ and ‘rhs’ dates do not have the // same value, and ‘false’ otherwise. Two ‘Date’ objects do not have // the same value if any of their respective ‘year’, ‘month’, and ‘day’ // attributes do not have the same value. std::ostream& operator<<(std::ostream& stream, const Date& date); // Format the value of the specified ‘date’ object to the specified // output ‘stream’ as ‘yyyy/mm/dd’.

Page 79: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

79

2. Interfaces and Contracts (review)

Interfaces and Contracts

Component

class Date { // … public: // … };

bool operator==(const Date& lhs, const Date& rhs); // Return ‘true’ if the specified ‘lhs’ and ‘rhs’ dates have the same // value, and ‘false’ otherwise. Two ‘Date’ objects have the same // value if their respective ‘year’, ‘month’, and ‘day’ attributes // have the same value. bool operator!=(const Date& lhs, const Date& rhs); // Return ‘true’ if the specified ‘lhs’ and ‘rhs’ dates do not have the // same value, and ‘false’ otherwise. Two ‘Date’ objects do not have // the same value if any of their respective ‘year’, ‘month’, and ‘day’ // attributes do not have the same value. std::ostream& operator<<(std::ostream& stream, const Date& date); // Format the value of the specified ‘date’ object to the specified // output ‘stream’ as ‘yyyy/mm/dd’, and return a reference to ‘stream’.

Page 80: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

2. Interfaces and Contracts (review)

Preconditions and Postconditions

80

Page 81: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

2. Interfaces and Contracts (review)

Preconditions and Postconditions

Function

81

Page 82: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

2. Interfaces and Contracts (review)

Preconditions and Postconditions

Function double sqrt(double value); // Return the square root of the specified ‘value’. // The behavior is undefined unless ‘0 <= value’.

82

Page 83: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

2. Interfaces and Contracts (review)

Preconditions and Postconditions

Function double sqrt(double value); // Return the square root of the specified ‘value’. // The behavior is undefined unless ‘0 <= value’.

83

Page 84: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

2. Interfaces and Contracts (review)

Preconditions and Postconditions

Function double sqrt(double value); // Return the square root of the specified ‘value’. // The behavior is undefined unless ‘0 <= value’.

Precondition

84

Page 85: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

2. Interfaces and Contracts (review)

Preconditions and Postconditions

Function double sqrt(double value); // Return the square root of the specified ‘value’. // The behavior is undefined unless ‘0 <= value’.

Precondition For a Stateless Function:

Restriction on syntactically legal inputs. 85

Page 86: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

2. Interfaces and Contracts (review)

Preconditions and Postconditions

Function double sqrt(double value); // Return the square root of the specified ‘value’. // The behavior is undefined unless ‘0 <= value’.

86

Page 87: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

2. Interfaces and Contracts (review)

Preconditions and Postconditions

Function double sqrt(double value); // Return the square root of the specified ‘value’. // The behavior is undefined unless ‘0 <= value’.

Postcondition

87

Page 88: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

2. Interfaces and Contracts (review)

Preconditions and Postconditions

Function double sqrt(double value); // Return the square root of the specified ‘value’. // The behavior is undefined unless ‘0 <= value’.

Postcondition

For a Stateless Function:

What it “returns.” 88

Page 89: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

2. Interfaces and Contracts (review)

Preconditions and Postconditions

Object Method

89

Page 90: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

2. Interfaces and Contracts (review)

Preconditions and Postconditions

Object Method

Preconditions: What must be true of both (object) state and method inputs; otherwise the behavior is undefined.

90

Page 91: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

2. Interfaces and Contracts (review)

Preconditions and Postconditions

Object Method

Preconditions: What must be true of both (object) state and method inputs; otherwise the behavior is undefined.

Postconditions: What must happen as a function of (object) state and input if all Preconditions are satisfied.

91

Page 92: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

2. Interfaces and Contracts (review)

Preconditions and Postconditions

Object Method

Preconditions: What must be true of both (object) state and method inputs; otherwise the behavior is undefined.

Postconditions: What must happen as a function of (object) state and input if all Preconditions are satisfied.

92

Page 93: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

2. Interfaces and Contracts (review)

Preconditions and Postconditions

93

Object Method

Preconditions: What must be true of both (object) state and method inputs; otherwise the behavior is undefined.

Postconditions: What must happen as a function of (object) state and method inputs if all preconditions are satisfied.

Observation By

Kevlin Henny

Note that Essential Behavior refers to a superset of Postconditions that includes

behavioral guarantees, such as runtime complexity.

Page 94: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

Defined & Essential Behavior

2. Interfaces and Contracts (review)

Preconditions and Postconditions

Undefined Behavior 94

Not

Undefined

Behavior

Page 95: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

Defined & Essential Behavior

2. Interfaces and Contracts (review)

Preconditions and Postconditions

Essential Behavior

Undefined Behavior 95

Page 96: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

Defined & Essential Behavior

2. Interfaces and Contracts (review)

Preconditions and Postconditions

Essential Behavior

Undefined Behavior 96

Defined but not

Essential

Page 97: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

Defined & Essential Behavior

2. Interfaces and Contracts (review)

Preconditions and Postconditions

Essential Behavior

Undefined Behavior 97

Defined but not

Essential

Unspecified and Implementation

-dependent

Page 98: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

Defined & Essential Behavior

2. Interfaces and Contracts (review)

Preconditions and Postconditions

std::ostream& print(std::ostream& stream,

int level = 0,

int spacesPerLevel = 4) const;

// Format this object to the specified output 'stream' at the (absolute

// value of) the optionally specified indentation 'level' and return a

// reference to 'stream'. If 'level' is specified, optionally specify

// 'spacesPerLevel', the number of spaces per indentation level for

// this and all of its nested objects. If 'level' is negative,

// suppress indentation of the first line. If 'spacesPerLevel' is

// negative, format the entire output on one line, suppressing all but

// the initial indentation (as governed by 'level'). If 'stream' is

// not valid on entry, this operation has no effect. 98

Page 99: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

Defined & Essential Behavior

2. Interfaces and Contracts (review)

Preconditions and Postconditions

std::ostream& print(std::ostream& stream,

int level = 0,

int spacesPerLevel = 4) const;

// Format this object to the specified output 'stream' at the (absolute

// value of) the optionally specified indentation 'level' and return a

// reference to 'stream'. If 'level' is specified, optionally specify

// 'spacesPerLevel', the number of spaces per indentation level for

// this and all of its nested objects. If 'level' is negative,

// suppress indentation of the first line. If 'spacesPerLevel' is

// negative, format the entire output on one line, suppressing all but

// the initial indentation (as governed by 'level'). If 'stream' is

// not valid on entry, this operation has no effect. 99

Page 100: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

Defined & Essential Behavior

2. Interfaces and Contracts (review)

Preconditions and Postconditions

std::ostream& print(std::ostream& stream,

int level = 0,

int spacesPerLevel = 4) const;

// Format this object to the specified output 'stream' at the (absolute

// value of) the optionally specified indentation 'level' and return a

// reference to 'stream'. If 'level' is specified, optionally specify

// 'spacesPerLevel', the number of spaces per indentation level for

// this and all of its nested objects. If 'level' is negative,

// suppress indentation of the first line. If 'spacesPerLevel' is

// negative, format the entire output on one line, suppressing all but

// the initial indentation (as governed by 'level'). If 'stream' is

// not valid on entry, this operation has no effect. 100

Page 101: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

Defined & Essential Behavior

2. Interfaces and Contracts (review)

Preconditions and Postconditions

std::ostream& print(std::ostream& stream,

int level = 0,

int spacesPerLevel = 4) const;

// Format this object to the specified output 'stream' at the (absolute

// value of) the optionally specified indentation 'level' and return a

// reference to 'stream'. If 'level' is specified, optionally specify

// 'spacesPerLevel', the number of spaces per indentation level for

// this and all of its nested objects. If 'level' is negative,

// suppress indentation of the first line. If 'spacesPerLevel' is

// negative, format the entire output on one line, suppressing all but

// the initial indentation (as governed by 'level'). If 'stream' is

// not valid on entry, this operation has no effect. 101

Page 102: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

Defined & Essential Behavior

2. Interfaces and Contracts (review)

Preconditions and Postconditions

std::ostream& print(std::ostream& stream,

int level = 0,

int spacesPerLevel = 4) const;

// Format this object to the specified output 'stream' at the (absolute

// value of) the optionally specified indentation 'level' and return a

// reference to 'stream'. If 'level' is specified, optionally specify

// 'spacesPerLevel', the number of spaces per indentation level for

// this and all of its nested objects. If 'level' is negative,

// suppress indentation of the first line. If 'spacesPerLevel' is

// negative, format the entire output on one line, suppressing all but

// the initial indentation (as governed by 'level'). If 'stream' is

// not valid on entry, this operation has no effect. 102

Page 103: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

Defined & Essential Behavior

2. Interfaces and Contracts (review)

Preconditions and Postconditions

std::ostream& print(std::ostream& stream,

int level = 0,

int spacesPerLevel = 4) const;

// Format this object to the specified output 'stream' at the (absolute

// value of) the optionally specified indentation 'level' and return a

// reference to 'stream'. If 'level' is specified, optionally specify

// 'spacesPerLevel', the number of spaces per indentation level for

// this and all of its nested objects. If 'level' is negative,

// suppress indentation of the first line. If 'spacesPerLevel' is

// negative, format the entire output on one line, suppressing all but

// the initial indentation (as governed by 'level'). If 'stream' is

// not valid on entry, this operation has no effect.

Any Undefined Behavior?

103

Page 104: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

Defined & Essential Behavior

2. Interfaces and Contracts (review)

Preconditions and Postconditions

std::ostream& print(std::ostream& stream,

int level = 0,

int spacesPerLevel = 4) const;

// Format this object to the specified output 'stream' at the (absolute

// value of) the optionally specified indentation 'level' and return a

// reference to 'stream'. If 'level' is specified, optionally specify

// 'spacesPerLevel', the number of spaces per indentation level for

// this and all of its nested objects. If 'level' is negative,

// suppress indentation of the first line. If 'spacesPerLevel' is

// negative, format the entire output on one line, suppressing all but

// the initial indentation (as governed by 'level'). If 'stream' is

// not valid on entry, this operation has no effect.

Any Non-Essential

Behavior?

104

Page 105: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

Defined & Essential Behavior

2. Interfaces and Contracts (review)

Preconditions and Postconditions

std::ostream& print(std::ostream& stream,

int level = 0,

int spacesPerLevel = 4) const;

// Format this object to the specified output 'stream' at the (absolute

// value of) the optionally specified indentation 'level' and return a

// reference to 'stream'. If 'level' is specified, optionally specify

// 'spacesPerLevel', the number of spaces per indentation level for

// this and all of its nested objects. If 'level' is negative,

// suppress indentation of the first line. If 'spacesPerLevel' is

// negative, format the entire output on one line, suppressing all but

// the initial indentation (as governed by 'level'). If 'stream' is

// not valid on entry, this operation has no effect.

Any Non-Essential

Behavior?

105

Hint

Page 106: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

Defined & Essential Behavior

2. Interfaces and Contracts (review)

Preconditions and Postconditions

class Date { // This class implements a value-semantic type representing // a valid date in history between the dates 0001/01/01 and // 9999/12/31 inclusive.

//…

public:

Date(int year, int month, int day); // Create a valid date from the specified ‘year’, ‘month’, and // ‘day’. The behavior is undefined unless ‘year’/’month’/’day’ // represents a valid date in the range [0001/01/01 .. 9999/12/31].

Date(const Date& original); // Create a date having the value of the specified ‘original’ date. // … };

106

Page 107: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

Defined & Essential Behavior

2. Interfaces and Contracts (review)

Preconditions and Postconditions

class Date { // This class implements a value-semantic type representing // a valid date in history between the dates 0001/01/01 and // 9999/12/31 inclusive.

//…

public:

Date(int year, int month, int day); // Create a valid date from the specified ‘year’, ‘month’, and // ‘day’. The behavior is undefined unless ‘year’/’month’/’day’ // represents a valid date in the range [0001/01/01 .. 9999/12/31].

Date(const Date& original); // Create a date having the value of the specified ‘original’ date. // … };

Any Undefined Behavior?

107

Page 108: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

Defined & Essential Behavior

2. Interfaces and Contracts (review)

Preconditions and Postconditions

class Date { // This class implements a value-semantic type representing // a valid date in history between the dates 0001/01/01 and // 9999/12/31 inclusive.

//…

public:

Date(int year, int month, int day); // Create a valid date from the specified ‘year’, ‘month’, and // ‘day’. The behavior is undefined unless ‘year’/’month’/’day’ // represents a valid date in the range [0001/01/01 .. 9999/12/31].

Date(const Date& original); // Create a date having the value of the specified ‘original’ date. // … };

Any Undefined Behavior?

108

Page 109: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

Defined & Essential Behavior

2. Interfaces and Contracts (review)

Preconditions and Postconditions

class Date { // This class implements a value-semantic type representing // a valid date in history between the dates 0001/01/01 and // 9999/12/31 inclusive.

//…

public:

Date(int year, int month, int day); // Create a valid date from the specified ‘year’, ‘month’, and // ‘day’. The behavior is undefined unless ‘year’/’month’/’day’ // represents a valid date in the range [0001/01/01 .. 9999/12/31].

Date(const Date& original); // Create a date having the value of the specified ‘original’ date. // … };

109

Page 110: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

Defined & Essential Behavior

2. Interfaces and Contracts (review)

Preconditions and Postconditions

class Date { // This class implements a value-semantic type representing // a valid date in history between the dates 0001/01/01 and // 9999/12/31 inclusive.

//…

public:

Date(int year, int month, int day); // Create a valid date from the specified ‘year’, ‘month’, and // ‘day’. The behavior is undefined unless ‘year’/’month’/’day’ // represents a valid date in the range [0001/01/01 .. 9999/12/31].

Date(const Date& original); // Create a date having the value of the specified ‘original’ date. // … };

Any Undefined Behavior?

110

Page 111: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

(Object) Invariants

2. Interfaces and Contracts (review)

Preconditions and Postconditions

class Date { // This class implements a value-semantic type representing // a valid date in history between the dates 0001/01/01 and // 9999/12/31 inclusive.

//…

public:

Date(int year, int month, int day); // Create a valid date from the specified ‘year’, ‘month’, and // ‘day’. The behavior is undefined unless ‘year’/’month’/’day’ // represents a valid date in the range [0001/01/01 .. 9999/12/31].

Date(const Date& original); // Create a date having the value of the specified ‘original’ date. // … };

111

Page 112: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

(Object) Invariants

2. Interfaces and Contracts (review)

Preconditions and Postconditions

class Date { // This class implements a value-semantic type representing // a valid date in history between the dates 0001/01/01 and // 9999/12/31 inclusive.

//…

public:

Date(int year, int month, int day); // Create a valid date from the specified ‘year’, ‘month’, and // ‘day’. The behavior is undefined unless ‘year’/’month’/’day’ // represents a valid date in the range [0001/01/01 .. 9999/12/31].

Date(const Date& original); // Create a date having the value of the specified ‘original’ date. // … };

112

Page 113: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

(Object) Invariants

2. Interfaces and Contracts (review)

Preconditions and Postconditions

class Date { // This class implements a value-semantic type representing // a valid date in history between the dates 0001/01/01 and // 9999/12/31 inclusive.

//…

public:

Date(int year, int month, int day); // Create a valid date from the specified ‘year’, ‘month’, and // ‘day’. The behavior is undefined unless ‘year’/’month’/’day’ // represents a valid date in the range [0001/01/01 .. 9999/12/31].

Date(const Date& original); // Create a date having the value of the specified ‘original’ date. // … };

113

Page 114: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

(Object) Invariants

2. Interfaces and Contracts (review)

Preconditions and Postconditions

class Date { // This class implements a value-semantic type representing // a valid date in history between the dates 0001/01/01 and // 9999/12/31 inclusive.

//…

public:

Date(int year, int month, int day); // Create a valid date from the specified ‘year’, ‘month’, and // ‘day’. The behavior is undefined unless ‘year’/’month’/’day’ // represents a valid date in the range [0001/01/01 .. 9999/12/31].

Date(const Date& original); // Create a date having the value of the specified ‘original’ date. // … };

114

Page 115: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

(Object) Invariants

2. Interfaces and Contracts (review)

Preconditions and Postconditions

class Date { // This class implements a value-semantic type representing // a valid date in history between the dates 0001/01/01 and // 9999/12/31 inclusive.

//…

public:

Date(int year, int month, int day); // Create a valid date from the specified ‘year’, ‘month’, and // ‘day’. The behavior is undefined unless ‘year’/’month’/’day’ // represents a valid date in the range [0001/01/01 .. 9999/12/31].

Date(const Date& original); // Create a date having the value of the specified ‘original’ date. // … };

115

Page 116: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

(Object) Invariants

2. Interfaces and Contracts (review)

Preconditions and Postconditions

class Date { // This class implements a value-semantic type representing // a valid date in history between the dates 0001/01/01 and // 9999/12/31 inclusive.

//…

public:

Date(int year, int month, int day); // Create a valid date from the specified ‘year’, ‘month’, and // ‘day’. The behavior is undefined unless ‘year’/’month’/’day’ // represents a valid date in the range [0001/01/01 .. 9999/12/31].

Date(const Date& original); // Create a date having the value of the specified ‘original’ date. // … };

116

Page 117: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

2. Interfaces and Contracts (review)

Design by Contract

117

Page 118: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

(DbC)

“If you give me valid input*, I will behave as advertised; otherwise, all bets are off!”

*including state

2. Interfaces and Contracts (review)

Design by Contract

118

Page 119: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

There are five aspects: 1. What it does. 2. What it returns. 3. Essential Behavior. 4. Undefined Behavior. 5. Note that…

2. Interfaces and Contracts (review)

Design by Contract

Documentation

119

Page 120: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

There are five aspects: 1. What it does. 2. What it returns. 3. Essential Behavior. 4. Undefined Behavior. 5. Note that…

2. Interfaces and Contracts (review)

Design by Contract

Documentation

120

Page 121: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

There are five aspects: 1. What it does. 2. What it returns. 3. Essential Behavior. 4. Undefined Behavior. 5. Note that…

2. Interfaces and Contracts (review)

Design by Contract

Documentation

121

Page 122: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

There are five aspects: 1. What it does. 2. What it returns. 3. Essential Behavior. 4. Undefined Behavior. 5. Note that…

2. Interfaces and Contracts (review)

Design by Contract

Documentation

122

Page 123: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

There are five aspects: 1. What it does. 2. What it returns. 3. Essential Behavior. 4. Undefined Behavior. 5. Note that…

2. Interfaces and Contracts (review)

Design by Contract

Documentation

123

Page 124: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

There are five aspects: 1. What it does. 2. What it returns. 3. Essential Behavior. 4. Undefined Behavior. 5. Note that…

2. Interfaces and Contracts (review)

Design by Contract

Documentation

124

Page 125: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

Invariants: Assert invariants in the destructor.

2. Interfaces and Contracts (review)

Design by Contract

Verification

125

Page 126: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

Preconditions: Invariants: Assert invariants in the destructor.

2. Interfaces and Contracts (review)

Design by Contract

Verification

126

Page 127: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

Preconditions: RTFM (Read the Manual).

Invariants: Assert invariants in the destructor.

2. Interfaces and Contracts (review)

Design by Contract

Verification

127

Page 128: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

Preconditions: RTFM (Read the Manual). Assert (only in ‘debug’ or ‘safe’ mode).

Invariants: Assert invariants in the destructor.

2. Interfaces and Contracts (review)

Design by Contract

Verification

128

Page 129: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

Preconditions: RTFM (Read the Manual). Assert (only in ‘debug’ or ‘safe’ mode).

Postconditions: Invariants: Assert invariants in the destructor.

2. Interfaces and Contracts (review)

Design by Contract

Verification

129

Page 130: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

Preconditions: RTFM (Read the Manual). Assert (only in ‘debug’ or ‘safe’ mode).

Postconditions: Component-level test drivers.

Invariants: Assert invariants in the destructor.

2. Interfaces and Contracts (review)

Design by Contract

Verification

130

Page 131: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

Preconditions: RTFM (Read the Manual). Assert (only in ‘debug’ or ‘safe’ mode).

Postconditions: Component-level test drivers.

Invariants: Assert invariants in the destructor.

2. Interfaces and Contracts (review)

Design by Contract

Verification

131

Page 132: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

Preconditions: RTFM (Read the Manual). Assert (only in ‘debug’ or ‘safe’ mode).

Postconditions: Component-level test drivers.

Invariants: Assert invariants in the destructor.

2. Interfaces and Contracts (review)

Design by Contract

Verification

132

Page 133: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

133

Preconditions always Imply Postconditions:

2. Interfaces and Contracts (review)

Contracts and Exceptions

Page 134: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

134

Preconditions always Imply Postconditions:

If a function cannot satisfy its contract (given valid

preconditions) it must not return normally.

2. Interfaces and Contracts (review)

Contracts and Exceptions

Page 135: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

135

Preconditions always Imply Postconditions:

If a function cannot satisfy its contract (given valid

preconditions) it must not return normally.

abort() should be considered a viable alternative to

throw in virtually all cases (if exceptions are disabled).

2. Interfaces and Contracts (review)

Contracts and Exceptions

Page 136: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

136

Preconditions always Imply Postconditions:

If a function cannot satisfy its contract (given valid

preconditions) it must not return normally.

abort() should be considered a viable alternative to

throw in virtually all cases (if exceptions are disabled).

Good library components are exception agnostic (via RAII).

2. Interfaces and Contracts (review)

Contracts and Exceptions

Page 137: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

Questions?

2. Interfaces and Contracts (review)

End of Section

137

Page 138: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

138

2. Interfaces and Contracts (review)

What Questions are we Answering? • What do we mean by Interface versus Contract for a

function, a class, or a component? • What do we mean by preconditions, postconditions,

and invariants? • What do we mean by essential & undefined behavior? • Must the code itself preserve invariants even if one or

more preconditions of the contract are violated? • What is the idea behind Design-by-Contract (DbC)? • How do we document the contract for a function? • How can clients ensure that preconditions are satisfied? • How do we guarantee that postconditions are satisfied? • How can we test to make sure invariants are preserved? • What must be true if a client satisfies all preconditions?

Page 139: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

139

Outline

1. Components (review)

Modularity, Logical/Physical Dependencies, & Level numbers

2. Interfaces and Contracts (review)

Syntax versus Semantics & Essential Behavior

3. Narrow versus Wide Contracts (review)

The Significance of Undefined Behavior

4. Proper Inheritance Is-A for Interface, Structural, & Implementation Inheritance

Page 140: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

140

Outline

1. Components (review)

Modularity, Logical/Physical Dependencies, & Level numbers

2. Interfaces and Contracts (review)

Syntax versus Semantics & Essential Behavior

3. Narrow versus Wide Contracts (review)

The Significance of Undefined Behavior

4. Proper Inheritance Is-A for Interface, Structural, & Implementation Inheritance

Page 141: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

141

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Page 142: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

142

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Pejorative terms:

Page 143: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

143

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Pejorative terms:

•Fat Interface (4. Proper Inheritance)

Page 144: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

144

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Pejorative terms:

•Fat Interface (4. Proper Inheritance)

•Large (Non-Primitive) Interface

Page 145: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

145

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Pejorative terms:

•Fat Interface (4. Proper Inheritance)

•Large (Non-Primitive) Interface

•Wide Contract

Page 146: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

146

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior:

Page 147: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

147

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: What should happen with the following call?

int x = std::strlen(0);

Page 148: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

148

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: What should happen with the following call?

int x = std::strlen(0);

How about it must return 0?

Page 149: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

149

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior:

int strlen(const char *s)

{

if (!s) return 0;

// …

}

How about it must return 0?

Wide

Page 150: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

150

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior:

int strlen(const char *s)

{

if (!s) return 0;

// …

}

How about it must return 0?

Wide

Likely to mask a defect

Page 151: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

151

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior:

int strlen(const char *s)

{

if (!s) return 0;

// …

}

How about it must return 0?

Wide

Likely to mask a defect

Page 152: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

152

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: What should happen with the following call?

int x = std::strlen(0);

Page 153: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

153

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: What should happen with the following call?

int x = std::strlen(0);

Page 154: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

154

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior:

int strlen(const char *s)

{

assert(s);

// …

}

Narrow

Page 155: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

155

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior:

int strlen(const char *s)

{

// …

}

Narrow

Page 156: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

156

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior:

int strlen(const char *s)

{

// …

}

Narrow

Page 157: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

157

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: Should

Date::setDate(int, int, int);

Return a status?

Page 158: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

158

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: Should

Date::setDate(int, int, int);

Return a status?

Page 159: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

159

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: I “know” this date is valid (It’s my birthday)!

date.setDate(3, 8, 59);

Therefore, why should I bother to check status?

date.setDate(1959, 3, 8);

Page 160: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

160

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: I “know” this date is valid (It’s my birthday)!

date.setDate(3, 8, 59);

Therefore, why should I bother to check status?

date.setDate(1959, 3, 8);

Page 161: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

161

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: I “know” this date is valid (It’s my birthday)!

date.setDate(3, 8, 59);

Therefore, why should I bother to check status?

date.setDate(1959, 3, 8);

Page 162: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

162

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior:

Returning status implies a wide contract.

Page 163: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

163

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior:

Returning status implies a wide contract.

Wide contracts prevent defending against such errors in any build mode.

Page 164: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

164

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior:

void Date::setDate(int y, int m, int d) { assert(isValid(y,m,d)); d_year = y; d_month = m; d_day = d; }

Page 165: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

165

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior:

void Date::setDate(int y, int m, int d) { assert(isValid(y,m,d)); d_year = y; d_month = m; d_day = d; }

Page 166: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

166

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior:

void Date::setDate(int y, int m, int d) { assert(isValid(y,m,d)); d_year = y; d_month = m; d_day = d; }

Narrow Contract:

Checked Only In

“Debug Mode”

Page 167: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

167

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: int Date::setDateIfValid(int y, int m, int d) { if (!isValid(y, m, d)) { return !0; } d_year = y; d_month = m; d_day = d; return 0; }

Page 168: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

168

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: int Date::setDateIfValid(int y, int m, int d) { if (!isValid(y, m, d)) { return !0; } d_year = y; d_month = m; d_day = d; return 0; }

Wide Contract:

Checked in

Every Build Mode

Page 169: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

169

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: • What should happen when the behavior is

undefined? TYPE& vector::operator[](int idx);

Page 170: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

170

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: • What should happen when the behavior is

undefined? TYPE& vector::operator[](int idx);

• Should what happens be part of the contract?

TYPE& vector::at(int idx);

Page 171: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

171

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: • What should happen when the behavior is

undefined? It depends on the build mode. TYPE& vector::operator[](int idx);

• Should what happens be part of the contract?

TYPE& vector::at(int idx);

Page 172: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

172

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: • What should happen when the behavior is

undefined? It depends on the build mode. TYPE& vector::operator[](int idx);

• Should what happens be part of the contract? If it is, then it’s essential behavior!

TYPE& vector::at(int idx);

Page 173: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

173

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: • What should happen when the behavior is

undefined? It depends on the build mode. TYPE& vector::operator[](int idx);

• Should what happens be part of the contract? If it is, then it’s essential behavior!

TYPE& vector::at(int idx);

Page 174: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

174

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: • What should happen when the behavior is

undefined? It depends on the build mode. TYPE& vector::operator[](int idx);

• Should what happens be part of the contract? If it is, then it’s essential behavior!

TYPE& vector::at(int idx);

Page 175: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

175

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: Should the behavior for

void insert(int idx, const TYPE& value);

be defined when idx is greater than length() or less than zero?

Page 176: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

176

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: Should the behavior for

void insert(int idx, const TYPE& value);

be defined when idx is greater than length() or less than zero? If so, what should it be?

Page 177: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

177

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: Should the behavior for

void insert(int idx, const TYPE& value);

be defined when idx is greater than length() or less than zero? If so, what should it be?

if (idx < 0) idx = 0;

if (idx > length()) idx = length();

Page 178: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

178

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: Should the behavior for

void insert(int idx, const TYPE& value);

be defined when idx is greater than length() or less than zero? If so, what should it be?

if (idx < 0) idx = 0;

if (idx > length()) idx = length();

idx = abs(idx) % (length() + 1);

Page 179: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

179

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: Should the behavior for

void insert(int idx, const TYPE& value);

be defined when idx is greater than length() or less than zero? If so, what should it be?

if (idx < 0) idx = 0;

if (idx > length()) idx = length();

idx = abs(idx) % (length() + 1);

Page 180: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

180

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: Should the behavior for

void insert(int idx, const TYPE& value);

be defined when idx is greater than length() or less than zero? If so, what should it be?

if (idx < 0) idx = 0;

if (idx > length()) idx = length();

idx = abs(idx) % (length() + 1);

Page 181: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

181

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: Should the behavior for

void insert(int idx, const TYPE& value);

be defined when idx is greater than length() or less than zero? If so, what should it be?

if (idx < 0) idx = 0;

if (idx > length()) idx = length();

idx = abs(idx) % (length() + 1);

Page 182: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

182

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: Should the behavior for

void insert(int idx, const TYPE& value);

be defined when idx is greater than length() or less than zero?

Page 183: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

183

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: Should the behavior for

void insert(int idx, const TYPE& value);

be defined when idx is greater than length() or less than zero? Answer: No!

Page 184: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

184

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: Should the behavior for

void insert(int idx, const TYPE& value);

be defined when idx is greater than length() or less than zero? Answer: No!

assert(0 <= idx); assert(idx <= length());

Page 185: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

185

3. Narrow versus Wide Contracts (review)

Narrow versus Wide Contracts

Narrow Contracts Imply Undefined Behavior: Should the behavior for

void insert(int idx, const TYPE& value);

be defined when idx is greater than length() or less than zero? Answer: No!

assert(0 <= idx); assert(idx <= length());

Page 186: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

186

3. Narrow versus Wide Contracts (review)

Appropriately Narrow Contracts

Page 187: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

187

3. Narrow versus Wide Contracts (review)

Appropriately Narrow Contracts

Narrow, but not too narrow.

Page 188: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

188

3. Narrow versus Wide Contracts (review)

Appropriately Narrow Contracts

Narrow, but not too narrow.

Should the behavior for

void replace(int index,

const TYPE& value,

int numElements);

be defined when index is length() and numElements is zero?

Page 189: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

189

3. Narrow versus Wide Contracts (review)

Appropriately Narrow Contracts

0 1 2 3 4 5

1

2

3

4

0

numElements

index

5 E.g., length() is 5.

?

Page 190: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

190

3. Narrow versus Wide Contracts (review)

Appropriately Narrow Contracts

0 1 2 3 4 5

1

2

3

4

0

numElements

index

5 E.g., length() is 5.

?

void replace(int index, const TYPE& value, int numElements) { assert(0 <= index); assert(0 <= numElements); assert(index + numElements <= length()); // … }

Page 191: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

191

3. Narrow versus Wide Contracts (review)

Appropriately Narrow Contracts

0 1 2 3 4 5

1

2

3

4

0

numElements

index

5 E.g., length() is 5.

?

void replace(int index, const TYPE& value, int numElements) { assert(0 <= index); assert(0 <= numElements); assert(index + numElements <= length()); // … }

X

Page 192: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

192

3. Narrow versus Wide Contracts (review)

Appropriately Narrow Contracts

0 1 2 3 4 5

1

2

3

4

0

numElements

index

5 E.g., length() is 5.

?

void replace(int index, const TYPE& value, int numElements) { assert(0 <= index); assert(0 <= numElements); assert(index + numElements <= length()); // … }

Now a client would have to check for this special case.

X

Page 193: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

193

3. Narrow versus Wide Contracts (review)

Appropriately Narrow Contracts

0 1 2 3 4 5

1

2

3

4

0

numElements

index

5 E.g., length() is 5.

?

void replace(int index, const TYPE& value, int numElements) { assert(0 <= index); assert(0 <= numElements); assert(index + numElements <= length()); // … }

Now a client would have to check for this special case.

X

Page 194: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

194

3. Narrow versus Wide Contracts (review)

Appropriately Narrow Contracts

0 1 2 3 4 5

1

2

3

4

0

numElements

index

5 E.g., length() is 5.

?

void replace(int index, const TYPE& value, int numElements) { assert(0 <= index); assert(0 <= numElements); assert(index + numElements <= length()); // … }

Assuming no extra code is needed to handle it …

Page 195: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

195

3. Narrow versus Wide Contracts (review)

Appropriately Narrow Contracts

0 1 2 3 4 5

1

2

3

4

0

numElements

index

5 E.g., length() is 5.

!

void replace(int index, const TYPE& value, int numElements) { assert(0 <= index); assert(0 <= numElements); assert(index + numElements <= length()); // … }

Assuming no extra code is needed to handle it …

… it is naturally more efficient to allow it.

Page 196: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

196

3. Narrow versus Wide Contracts (review)

End of Section

Questions?

Page 197: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

197

3. Narrow versus Wide Contracts (review)

What Questions are we Answering? • What do we mean by a narrow versus a wide contract?

– Should std::strlen(0) be required to do something reasonable?

– Should Date::setDate(int, int, int) return a status?

• What should happen when the behavior is undefined? – Should what happens be part of the component-level contract?

• What about the behavior for these specific interfaces: – Should operator[](int index) check to see if index is less than

zero or greater than length()? • And what should happen if index is out of range?

– Should insert(int index, const TYPE& value) be defined when index is greater than length() or less than zero?

– Should replace(int index, const TYPE& value, int numElements) be defined when index is length() and numElements is zero?

• What do we mean by Defensive Programming (DP)?

Page 198: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

198

Outline

1. Components (review)

Modularity, Logical/Physical Dependencies, & Level numbers

2. Interfaces and Contracts (review)

Syntax versus Semantics & Essential Behavior

3. Narrow versus Wide Contracts (review)

The Significance of Undefined Behavior

4. Proper Inheritance Is-A for Interface, Structural, & Implementation Inheritance

Page 199: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

199

Outline

1. Components (review)

Modularity, Logical/Physical Dependencies, & Level numbers

2. Interfaces and Contracts (review)

Syntax versus Semantics & Essential Behavior

3. Narrow versus Wide Contracts (review)

The Significance of Undefined Behavior

4. Proper Inheritance Is-A for Interface, Structural, & Implementation Inheritance

Page 200: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

200

4. Proper Inheritance

Three Kinds of Inheritance

Page 201: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

201

4. Proper Inheritance

Three Kinds of Inheritance There are three kinds of inheritance because there are three kinds of member functions:

Page 202: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

202

4. Proper Inheritance

Three Kinds of Inheritance There are three kinds of inheritance because there are three kinds of member functions:

Public, Protected,

Private?

Page 203: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

203

4. Proper Inheritance

Three Kinds of Inheritance There are three kinds of inheritance because there are three kinds of member functions:

Public, Protected,

Private?

Page 204: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

204

4. Proper Inheritance

Three Kinds of Inheritance There are three kinds of inheritance because there are three kinds of member functions:

Page 205: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

205

4. Proper Inheritance

Three Kinds of Inheritance There are three kinds of inheritance because there are three kinds of member functions:

• Interface Inheritance: – Pure Virtual Functions

Page 206: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

206

4. Proper Inheritance

Three Kinds of Inheritance There are three kinds of inheritance because there are three kinds of member functions:

• Interface Inheritance: – Pure Virtual Functions

• Structural Inheritance: – Non-Virtual Functions

Page 207: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

207

4. Proper Inheritance

Three Kinds of Inheritance There are three kinds of inheritance because there are three kinds of member functions:

• Interface Inheritance: – Pure Virtual Functions

• Structural Inheritance: – Non-Virtual Functions

• Implementation Inheritance: –Non-Pure Virtual Functions

Page 208: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

208

4. Proper Inheritance

Interface Inheritance

class TcpChannel : public Channel {

/* … */

public:

// … (creators)

virtual int read(char *buffer, int numBytes) {…}

virtual int write(const char *buffer, int numBytes) {…}

};

class Channel {

public:

virtual ~Channel() { }

virtual int read(char *buffer, int numBytes) = 0;

virtual int write(const char *buffer, int numBytes) = 0;

};

TcpChannel

Channel

Page 209: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

209

4. Proper Inheritance

Structural Inheritance

class Pixel : public Point {

public:

enum Color { RED, GREEN, BLUE };

private:

Color d_color;

public:

// … (creators)

void setColor(Color color) { /* … */ }

Color color ( ) const { /* … */ } };

class Point {

int d_x;

int d_y;

public:

// … (creators)

void setX(int x) { /* … */ }

void setY(int y) { /* … */ }

int x() const { /* … */ }

int y() const { /* … */ }

};

Pixel

Point

Page 210: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

210

4. Proper Inheritance

Implementation Inheritance

class CompositeWidget : public Widget {

// …

public:

// … (creators)

virtual const char *widgetCategory() const { return "COMP"; }

virtual int numChildren() const { /* … */ }

// …

};

class Widget { Point d_origin;

// …

public:

// … (creators)

virtual bool isNameable() const { return false; }

virtual const char *instanceName() const { return 0; } virtual bool hasLocation() const { return true; }

virtual Point origin() const { return d_origin; }

virtual const char *widgetCategory() const { return "LEAF"; }

virtual int numChildren const { return 0; }

// … };

CompositeWidget

Widget

Page 211: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

211

4. Proper Inheritance

What Is Proper Inheritance?

Base

Derived

2

1

Is-Substitutable-For

Is-A

Implements

Extends

Page 212: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

212

4. Proper Inheritance

What Is Proper Inheritance? • The “IsA” Relationship?

– What does it mean?

Page 213: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

213

4. Proper Inheritance

What Is Proper Inheritance? • The “IsA” Relationship?

– What does it mean?

• Weaker Preconditions?

• Stronger Postconditions?

• Same Invariants?

Page 214: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

214

4. Proper Inheritance

What Is Proper Inheritance? • The “IsA” Relationship?

– What does it mean?

• Weaker Preconditions?

• Stronger Postconditions?

• Same Invariants?

• Providing a Proper Superset of Behavior?

Page 215: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

215

4. Proper Inheritance

What Is Proper Inheritance? • The “IsA” Relationship?

– What does it mean?

• Weaker Preconditions?

• Stronger Postconditions?

• Same Invariants?

• Providing a Proper Superset of Behavior?

• Substitutability? – Of what?

– What criteria?

Page 216: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

216

4. Proper Inheritance

What Is Proper Inheritance?

Base

Derived

2

1

Is-Substitutable-For

Is-A

Implements

Extends

Page 217: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

217

4. Proper Inheritance

What Is Proper Inheritance?

Base

Derived

2

1

Is-Substitutable-For

Is-A

Implements

Extends

The Is-A Relation:

The implementation

of a derived class

must satisfy

(simultaneously) its

own contract, as

well as that of

“each” base class.

Page 218: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

218

4. Proper Inheritance

What Is Proper Inheritance?

What about the following general property:

For inheritance to be proper, any operation that can be invoked on a derived-class object via a base-class pointer (or reference) must behave identically if we replace that base-class pointer (or reference) with a corresponding derived-class one.

Note that this is how virtual functions behave!

Page 219: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

219

4. Proper Inheritance

What Is Proper Inheritance?

What about the following general property:

For inheritance to be proper, any operation that can be invoked on a derived-class object via a base-class pointer (or reference) must behave identically if we replace that base-class pointer (or reference) with a corresponding derived-class one.

Note that this is how virtual functions behave!

Page 220: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

220

4. Proper Inheritance

What Is Proper Inheritance?

What about the following general property:

For inheritance to be proper, any operation that can be invoked on a derived-class object via a base-class pointer (or reference) must behave identically if we replace that base-class pointer (or reference) with a corresponding derived-class one.

Note that this is how virtual functions behave!

Page 221: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

221

4. Proper Inheritance

What Is Proper Inheritance?

Derived

Base

f(int, double, const char *)

f(int, double, const char *)

Page 222: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

222

4. Proper Inheritance

What Is Proper Inheritance?

Derived

Base

f(int, double, const char *)

f(int, double, const char *)

Page 223: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

223

4. Proper Inheritance

What Is Proper Inheritance?

Derived

Base

f(int, double, const char *)

f(int, double, const char *)

Page 224: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

224

4. Proper Inheritance

What Is Proper Inheritance?

Derived

Base

f(int, double, const char *)

f(int, double, const char *)

Page 225: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

225

4. Proper Inheritance

What Is Proper Inheritance?

Derived *dp = new Derived();

Base *bp = dp; // bp = 0x002140

Derived

Base

f(int, double, const char *)

f(int, double, const char *)

Page 226: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

226

4. Proper Inheritance

What Is Proper Inheritance?

Derived *dp = new Derived(); // dp = 0x002140

Base *bp = dp; // bp = 0x002140

Derived

Base

f(int, double, const char *)

f(int, double, const char *)

0x002130:

0x002138:

0x002140:

0x002148:

0x002150:

0x002158:

0x002160:

0x002168:

0x002170:

Page 227: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

227

4. Proper Inheritance

What Is Proper Inheritance?

Derived *dp = new Derived(); // dp = 0x002140

Base *bp = dp; // bp = 0x002140

Derived

Base

f(int, double, const char *)

f(int, double, const char *)

0x002130:

0x002138:

0x002140:

0x002148:

0x002150:

0x002158:

0x002160:

0x002168:

0x002170:

Page 228: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

228

4. Proper Inheritance

What Is Proper Inheritance?

Derived *dp = new Derived(); // dp = 0x002140

Base *bp = dp; // bp = 0x002140

Derived

Base

f(int, double, const char *)

f(int, double, const char *) Object of type

Derived

0x002130:

0x002138:

0x002140:

0x002148:

0x002150:

0x002158:

0x002160:

0x002168:

0x002170:

Page 229: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

229

4. Proper Inheritance

What Is Proper Inheritance?

Derived *dp = new Derived(); // dp = 0x002140

Base *bp = dp; // bp = 0x002140

Derived

Base

f(int, double, const char *)

f(int, double, const char *) Object of type

Derived

0x002130:

0x002138:

0x002140:

0x002148:

0x002150:

0x002158:

0x002160:

0x002168:

0x002170:

Page 230: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

230

4. Proper Inheritance

What Is Proper Inheritance?

Derived *dp = new Derived(); // dp = 0x002140

Base *bp = dp; // bp = 0x002140

Derived

Base

f(int, double, const char *)

f(int, double, const char *) Object of type

Derived

0x002130:

0x002138:

0x002140:

0x002148:

0x002150:

0x002158:

0x002160:

0x002168:

0x002170:

Page 231: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

231

4. Proper Inheritance

What Is Proper Inheritance?

Derived *dp = new Derived(); // dp = 0x002140

Base *bp = dp; // bp = 0x002140

Derived

Base

f(int, double, const char *)

f(int, double, const char *) Object of type

Derived

0x002130:

0x002138:

0x002140:

0x002148:

0x002150:

0x002158:

0x002160:

0x002168:

0x002170:

Page 232: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

232

4. Proper Inheritance

What Is Proper Inheritance?

Derived *dp = new Derived(); // dp = 0x002140

Base *bp = dp; // bp = 0x002140

Derived

Base

f(int, double, const char *)

f(int, double, const char *) Object of type

Derived

0x002130:

0x002138:

0x002140:

0x002148:

0x002150:

0x002158:

0x002160:

0x002168:

0x002170:

Page 233: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

233

4. Proper Inheritance

What Is Proper Inheritance?

Derived *dp = new Derived(); // dp = 0x002140

Base *bp = dp; // bp = 0x002140

Derived

Base

f(int, double, const char *)

f(int, double, const char *) Object of type

Derived

0x002130:

0x002138:

0x002140:

0x002148:

0x002150:

0x002158:

0x002160:

0x002168:

0x002170:

Page 234: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

234

4. Proper Inheritance

What Is Proper Inheritance?

Derived *dp = new Derived(); // dp = 0x002140

Base *bp = dp; // bp = 0x002140

Derived

Base

f(int, double, const char *)

f(int, double, const char *) Object of type

Derived

0x002130:

0x002138:

0x002140:

0x002148:

0x002150:

0x002158:

0x002160:

0x002168:

0x002170:

bp->f(1, 2.0, “three”);

Page 235: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

235

4. Proper Inheritance

What Is Proper Inheritance?

Derived *dp = new Derived(); // dp = 0x002140

Base *bp = dp; // bp = 0x002140

Derived

Base

f(int, double, const char *)

f(int, double, const char *) Object of type

Derived

0x002130:

0x002138:

0x002140:

0x002148:

0x002150:

0x002158:

0x002160:

0x002168:

0x002170:

dp->f(1, 2.0, “three”);

bp->f(1, 2.0, “three”);

Page 236: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

236

4. Proper Inheritance

What Is Proper Inheritance?

Derived *dp = new Derived(); // dp = 0x002140

Base *bp = dp; // bp = 0x002140

Derived

Base

f(int, double, const char *)

f(int, double, const char *) Object of type

Derived

0x002130:

0x002138:

0x002140:

0x002148:

0x002150:

0x002158:

0x002160:

0x002168:

0x002170:

dp->f(1, 2.0, “three”);

bp->f(1, 2.0, “three”); Identical

Behavior

Page 237: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

237

4. Proper Inheritance

What Is Proper Inheritance?

What about the following general property:

For inheritance to be proper, any operation that can be invoked on a derived-class object via a base-class pointer (or reference) must behave identically if we replace that base-class pointer (or reference) with a corresponding derived-class one.

Note that this is how virtual functions behave!

Page 238: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

238

4. Proper Inheritance

What Is Proper Inheritance?

What about the following general property:

For inheritance to be proper, any operation that can be invoked on a derived-class object via a base-class pointer (or reference) must behave identically if we replace that base-class pointer (or reference) with a corresponding derived-class one.

Note that this is how virtual functions behave!

Page 239: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

239

4. Proper Inheritance

What Is Proper Inheritance?

Derived Interface

and Contract

Base Interface

and Contract

Derived

Base

h()

g(int)

g(int)

f(int)

f(int)

Base::g(int x); // Defined only for 0 <= x.

Derived::g(int x); // Defined for all x.

Base::f(int x); // Defined for all x.

Derived::f(int x); // Defined for all x.

Derived::h(); // Note: not accessible from Base class.

Page 240: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

240

4. Proper Inheritance

What Is Proper Inheritance?

Derived Interface

and Contract

Base Interface

and Contract

Derived

Base

h()

g(int)

g(int)

f(int)

f(int)

Base::g(int x); // Defined only for 0 <= x.

Derived::g(int x); // Defined for all x.

Base::f(int x); // Defined for all x.

Derived::f(int x); // Defined for all x.

Derived::h(); // Note: not accessible from Base class.

Page 241: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

241

4. Proper Inheritance

What Is Proper Inheritance?

Derived Interface

and Contract

Base Interface

and Contract

Derived

Base

h()

g(int)

g(int)

f(int)

f(int)

Base::g(int x); // Defined only for 0 <= x.

Derived::g(int x); // Defined for all x.

Base::f(int x); // Defined for all x.

Derived::f(int x); // Defined for all x.

Derived::h(); // Note: not accessible from Base class.

Page 242: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

242

4. Proper Inheritance

What Is Proper Inheritance?

Derived Interface

and Contract

Base Interface

and Contract

Derived

Base

h()

g(int)

g(int)

f(int)

f(int)

Base::g(int x); // Defined only for 0 <= x.

Derived::g(int x); // Defined for all x.

Base::f(int x); // Defined for all x.

Derived::f(int x); // Defined for all x.

Derived::h(); // Note: not accessible from Base class.

Page 243: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Pure Interface Inheritance

243

For each function D::f in the derived class overriding

a virtual one B::f in the base class, the (documented)

preconditions of D::f must be no stronger than

those for B::f, and the postconditions no weaker.

Derived

Base

Implementation

Interface

Constructors D::f

B::f

Page 244: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Pure Interface Inheritance

244

For each function D::f in the derived class overriding

a virtual one B::f in the base class, the (documented)

preconditions of D::f must be no stronger than

those for B::f, and the postconditions no weaker.

Derived

Base

Implementation

Interface

Constructors D::f

B::f

Implements the Interface

Page 245: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Pure Interface Inheritance

245

For each function D::f in the derived class overriding

a virtual one B::f in the base class, the (documented)

preconditions of D::f must be no stronger than

those for B::f, and the postconditions no weaker.

Derived

Base

Implementation

Interface

Constructors D::f

B::f

Implements the Interface

Page 246: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Pure Interface Inheritance

246

For each function D::f in the derived class overriding

a virtual one B::f in the base class, the (documented)

preconditions of D::f must be no stronger than

those for B::f, and the postconditions no weaker.

Derived

Base

Implementation

Interface

Constructors D::f

B::f

Implements the Interface

are typically the same as

Page 247: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

247

4. Proper Inheritance

Pure Interface Inheritance

Channel

B::f

Page 248: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

248

4. Proper Inheritance

Pure Interface Inheritance

Channel

B::f

virtual int write(const char *buffer, int numBytes) = 0;

// Write the specified 'numBytes' from the specified

// 'buffer'. Return 0 on success, and a non-zero value

// otherwise. The behavior is undefined unless

// '0 <= numBytes <= 32767'.

Page 249: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

249

4. Proper Inheritance

Pure Interface Inheritance

TcpChannel

Channel

D::f

B::f

virtual int write(const char *buffer, int numBytes) = 0;

// Write the specified 'numBytes' from the specified

// 'buffer'. Return 0 on success, and a non-zero value

// otherwise. The behavior is undefined unless

// '0 <= numBytes <= 32767'.

Page 250: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

250

4. Proper Inheritance

Pure Interface Inheritance

TcpChannel

Channel

D::f

B::f

virtual int write(const char *buffer, int numBytes);

// Write to this TCP/IP channel the specified

// 'numBytes' from the specified 'buffer'. Return 0 on

// success, and a non-zero value otherwise. The

// behavior is undefined unless '0 == numBytes % 4'.

virtual int write(const char *buffer, int numBytes) = 0;

// Write the specified 'numBytes' from the specified

// 'buffer'. Return 0 on success, and a non-zero value

// otherwise. The behavior is undefined unless

// '0 <= numBytes <= 32767'.

Page 251: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

251

4. Proper Inheritance

Pure Interface Inheritance

TcpChannel

Channel

D::f

B::f

virtual int write(const char *buffer, int numBytes);

// Write to this TCP/IP channel the specified

// 'numBytes' from the specified 'buffer'. Return 0 on

// success, 1 if '0 != numBytes % 4', and a negative

// value otherwise.

virtual int write(const char *buffer, int numBytes) = 0;

// Write the specified 'numBytes' from the specified

// 'buffer'. Return 0 on success, and a non-zero value

// otherwise. The behavior is undefined unless

// '0 <= numBytes <= 32767'.

Page 252: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

252

4. Proper Inheritance

Pure Interface Inheritance

TcpChannel

Channel

D::f

B::f

virtual int write(const char *buffer, int numBytes);

// Write to this TCP/IP channel the specified

// 'numBytes' from the specified 'buffer'. Return 0 on

// success, and a non-zero value otherwise. Note that

// this functionality is not yet implemented on Windows;

// on that platform, this function always returns -1.

virtual int write(const char *buffer, int numBytes) = 0;

// Write the specified 'numBytes' from the specified

// 'buffer'. Return 0 on success, and a non-zero value

// otherwise. The behavior is undefined unless

// '0 <= numBytes <= 32767'.

Page 253: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

253

4. Proper Inheritance

What Is a Proper Subtype/Subclass?

Page 254: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

254

4. Proper Inheritance

What Is a Proper Subtype/Subclass?

“A type hierarchy is composed of subtypes and supertypes. The intuitive

idea of a subtype is one whose objects provide all the behavior of objects

of another type (the supertype) plus something extra.” – Barbara Liskov . (OOPSLA ’87)

Page 255: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

255

4. Proper Inheritance

What Is a Proper Subtype/Subclass?

“A type hierarchy is composed of subtypes and supertypes. The intuitive

idea of a subtype is one whose objects provide all the behavior of objects

of another type (the supertype) plus something extra.” – Barbara Liskov . (OOPSLA ’87)

TcpChannel

Channel

Interface Inheritance

Can create it.

Page 256: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

256

4. Proper Inheritance

What Is a Proper Subtype/Subclass?

“A type hierarchy is composed of subtypes and supertypes. The intuitive

idea of a subtype is one whose objects provide all the behavior of objects

of another type (the supertype) plus something extra.” – Barbara Liskov . (OOPSLA ’87)

Pixel

Point

TcpChannel

Channel

Interface Inheritance

Structural Inheritance

Can create it. Can do something

more with it.

Page 257: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

257

4. Proper Inheritance

What Is a Proper Subtype/Subclass?

“A type hierarchy is composed of subtypes and supertypes. The intuitive

idea of a subtype is one whose objects provide all the behavior of objects

of another type (the supertype) plus something extra.” – Barbara Liskov . (OOPSLA ’87)

Pixel

Point

TcpChannel

Channel

CompositeWidget

Widget

Interface Inheritance

Structural Inheritance

Implementation Inheritance

Can create it. Can do something

more with it.

Can create something

else with it.

Page 258: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

What Is Liskov Substitution?

258

Page 259: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

What Is Liskov Substitution?

What exactly is the Liskov Substitution Principle (LSP)?

259

Page 260: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

What Is Liskov Substitution?

What exactly is the Liskov Substitution Principle (LSP)?

• What motivated LSP in the first place?

260

Page 261: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

What Is Liskov Substitution?

What exactly is the Liskov Substitution Principle (LSP)?

• What motivated LSP in the first place?

• (How?) Does LSP relate to inheritance in C++?

261

Page 262: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

What Is Liskov Substitution?

What exactly is the Liskov Substitution Principle (LSP)?

• What motivated LSP in the first place?

• (How?) Does LSP relate to inheritance in C++?

• After Liskov substitution is applied, can (observable) behavior be (subtly) different?

262

Page 263: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

What Is Liskov Substitution?

What exactly is the Liskov Substitution Principle (LSP)?

• What motivated LSP in the first place?

• (How?) Does LSP relate to inheritance in C++?

• After Liskov substitution is applied, can (observable) behavior be (subtly) different?

• Does LSP apply to all three kinds of inheritance?

263

Page 264: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

What Is Liskov Substitution?

What exactly is the Liskov Substitution Principle (LSP)?

• What motivated LSP in the first place?

• (How?) Does LSP relate to inheritance in C++?

• After Liskov substitution is applied, can (observable) behavior be (subtly) different?

• Does LSP apply to all three kinds of inheritance?

• Does LSP have any other practical applications?

264

Page 265: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

What Is Liskov Substitution?

What exactly is the Liskov Substitution Principle (LSP)?

• What motivated LSP in the first place?

• (How?) Does LSP relate to inheritance in C++?

• After Liskov substitution is applied, can (observable) behavior be (subtly) different?

• Does LSP apply to all three kinds of inheritance?

• Does LSP have any other practical applications?

• Let’s have a look…

265

Page 266: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

266

4. Proper Inheritance

What Is Liskov Substitution? “If for each object o1 of type S there is an object o2 of type T such that for

all programs P defined in terms of T, the behavior of P is unchanged when

o1 is substituted for o2, then S is a subtype of T.” – Barbara Liskov (OOPSLA ’87)

Page 267: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

267

4. Proper Inheritance

What Is Liskov Substitution? “If for each object o1 of type S there is an object o2 of type T such that for

all programs P defined in terms of T, the behavior of P is unchanged when

o1 is substituted for o2, then S is a subtype of T.” – Barbara Liskov (OOPSLA ’87)

Page 268: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

268

4. Proper Inheritance

What Is Liskov Substitution? “If for each object o1 of type S there is an object o2 of type T such that for

all programs P defined in terms of T, the behavior of P is unchanged when

o1 is substituted for o2, then S is a subtype of T.” – Barbara Liskov (OOPSLA ’87)

main()

{ Fool f0(false);

Fool f1(true);

// …

p(f1, f0, …);

}

Page 269: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

269

4. Proper Inheritance

What Is Liskov Substitution? “If for each object o1 of type S there is an object o2 of type T such that for

all programs P defined in terms of T, the behavior of P is unchanged when

o1 is substituted for o2, then S is a subtype of T.” – Barbara Liskov (OOPSLA ’87)

class Fool : public Bool {

public: Fool(int x) : Bool(!x) { } };

main()

{ Fool f0(false);

Fool f1(true);

// …

p(f1, f0, …);

}

Page 270: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

270

4. Proper Inheritance

What Is Liskov Substitution? “If for each object o1 of type S there is an object o2 of type T such that for

all programs P defined in terms of T, the behavior of P is unchanged when

o1 is substituted for o2, then S is a subtype of T.” – Barbara Liskov (OOPSLA ’87)

class Fool : public Bool {

public: Fool(int x) : Bool(!x) { } };

main()

{ Bool b0(false);

Bool b1(true);

// …

p(b0, b1, …);

}

main()

{ Fool f0(false);

Fool f1(true);

// …

p(f1, f0, …);

}

Page 271: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

271

4. Proper Inheritance

What Is Liskov Substitution? “If for each object o1 of type S there is an object o2 of type T such that for

all programs P defined in terms of T, the behavior of P is unchanged when

o1 is substituted for o2, then S is a subtype of T.” – Barbara Liskov (OOPSLA ’87)

class Bool {

bool d_v; public: Bool(int x) : d_v(x) { } operator bool() const {return d_v;} };

class Fool : public Bool {

public: Fool(int x) : Bool(!x) { } };

main()

{ Bool b0(false);

Bool b1(true);

// …

p(b0, b1, …);

}

main()

{ Fool f0(false);

Fool f1(true);

// …

p(f1, f0, …);

}

Page 272: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

272

4. Proper Inheritance

What Is Liskov Substitution? “If for each object o1 of type S there is an object o2 of type T such that for

all programs P defined in terms of T, the behavior of P is unchanged when

o1 is substituted for o2, then S is a subtype of T.” – Barbara Liskov (OOPSLA ’87)

class Bool {

bool d_v; public: Bool(int x) : d_v(x) { } operator bool() const {return d_v;} };

class Fool : public Bool {

public: Fool(int x) : Bool(!x) { } };

main()

{ Bool b0(false);

Bool b1(true);

// …

p(b0, b1, …);

}

void p(const Bool& x, const Bool& y, …) { /* … */ }

main()

{ Fool f0(false);

Fool f1(true);

// …

p(f1, f0, …);

}

Page 273: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

273

4. Proper Inheritance

What Is Liskov Substitution? “If for each object o1 of type S there is an object o2 of type T such that for

all programs P defined in terms of T, the behavior of P is unchanged when

o1 is substituted for o2, then S is a subtype of T.” – Barbara Liskov (OOPSLA ’87)

class Bool {

bool d_v; public: Bool(int x) : d_v(x) { } operator bool() const {return d_v;} };

class Fool : public Bool {

public: Fool(int x) : Bool(!x) { } };

main()

{ Bool b0(false);

Bool b1(true);

// …

p(b0, b1, …);

}

void p(const Bool& x, const Bool& y, …) { /* … */ }

main()

{ Fool f0(false);

Fool f1(true);

// …

p(f1, f0, …);

}

Note order is different!

Page 274: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

274

4. Proper Inheritance

What Is Liskov Substitution? “If for each object o1 of type S there is an object o2 of type T such that for

all programs P defined in terms of T, the behavior of P is unchanged when

o1 is substituted for o2, then S is a subtype of T.” – Barbara Liskov (OOPSLA ’87)

class Bool {

bool d_v; public: Bool(int x) : d_v(x) { } operator bool() const {return d_v;} };

class Fool : public Bool {

public: Fool(int x) : Bool(!x) { } };

main()

{ Bool b0(false);

Bool b1(true);

// …

p(b0, b1, …);

}

void p(const Bool& x, const Bool& y, …) { /* … */ }

main()

{ Fool f0(false);

Fool f1(true);

// …

p(f1, f0, …);

}

Page 275: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

275

4. Proper Inheritance

What Is Liskov Substitution? “If for each object o1 of type S there is an object o2 of type T such that for

all programs P defined in terms of T, the behavior of P is unchanged when

o1 is substituted for o2, then S is a subtype of T.” – Barbara Liskov (OOPSLA ’87)

class Bool {

bool d_v; public: Bool(int x) : d_v(x) { } operator bool() const {return d_v;} };

class Fool : public Bool {

public: Fool(int x) : Bool(!x) { } };

main()

{ Bool b0(false);

Bool b1(true);

// …

p(b0, b1, …);

}

void p(const Bool& x, const Bool& y, …) { /* … */ }

main()

{ Fool f0(false);

Fool f1(true);

// …

p(f1, f0, …);

}

Note order is different!

Page 276: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

276

4. Proper Inheritance

What Is Liskov Substitution? “If for each object o1 of type S there is an object o2 of type T such that for

all programs P defined in terms of T, the behavior of P is unchanged when

o1 is substituted for o2, then S is a subtype of T.” – Barbara Liskov (OOPSLA ’87)

Page 277: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

277

4. Proper Inheritance

What Is Liskov Substitution? “If for each object o1 of type S there is an object o2 of type T such that for

all programs P defined in terms of T, the behavior of P is unchanged when

o1 is substituted for o2, then S is a subtype of T.” – Barbara Liskov (OOPSLA ’87)

Page 278: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

278

4. Proper Inheritance

What Is Liskov Substitution? “If for each object o1 of type S there is an object o2 of type T such that for

all programs P defined in terms of T, the behavior of P is unchanged when

o1 is substituted for o2, then S is a subtype of T.” – Barbara Liskov (OOPSLA ’87)

If, for each “derived-class” object o1 of type S, there exists a “base-class”

object o2 of type T such that, for all programs P defined in terms of type T,

the behavior of P is unchanged when the “derived-class” object o1 is

substituted for the “base-class” object o2, then S is a subtype of T.

Page 279: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

279

4. Proper Inheritance

What Is Liskov Substitution?

If, for each “derived-class” object d of type D, there exists a “base-class”

object b of type B such that, for all programs P defined in terms of type B,

the behavior of P is unchanged when the “derived-class” object d is

substituted for the “base-class” object b, then D is a subtype of B.

If, for each “derived-class” object o1 of type S, there exists a “base-class”

object o2 of type T such that, for all programs P defined in terms of type T,

the behavior of P is unchanged when the “derived-class” object o1 is

substituted for the “base-class” object o2, then S is a subtype of T.

“If for each object o1 of type S there is an object o2 of type T such that for

all programs P defined in terms of T, the behavior of P is unchanged when

o1 is substituted for o2, then S is a subtype of T.” – Barbara Liskov (OOPSLA ’87)

Page 280: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

280

4. Proper Inheritance

What Is Liskov Substitution? “If for each object o1 of type S there is an object o2 of type T such that for

all programs P defined in terms of T, the behavior of P is unchanged when

o1 is substituted for o2, then S is a subtype of T.” – Barbara Liskov (OOPSLA ’87)

If, for each “derived-class” object o1 of type S, there exists a “base-class”

object o2 of type T such that, for all programs P defined in terms of type T,

the behavior of P is unchanged when the “derived-class” object o1 is

substituted for the “base-class” object o2, then S is a subtype of T.

If, for each “derived-class” object d of type D, there exists a “base-class”

object b of type B such that, for all programs P defined in terms of type B,

the behavior of P is unchanged when the “derived-class” object d is

substituted for the “base-class” object b, then D is a subtype of B.

If, for each object d of type D, there exists an object b of type B such that,

for all programs P defined in terms of B, the behavior of P is unchanged

when d is substituted for b, then D is a subtype of B.

Page 281: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

281

4. Proper Inheritance

What Is Liskov Substitution? “If for each object o1 of type S there is an object o2 of type T such that for

all programs P defined in terms of T, the behavior of P is unchanged when

o1 is substituted for o2, then S is a subtype of T.” – Barbara Liskov (OOPSLA ’87)

If, for each “derived-class” object o1 of type S, there exists a “base-class”

object o2 of type T such that, for all programs P defined in terms of type T,

the behavior of P is unchanged when the “derived-class” object o1 is

substituted for the “base-class” object o2, then S is a subtype of T.

If, for each “derived-class” object d of type D, there exists a “base-class”

object b of type B such that, for all programs P defined in terms of type B,

the behavior of P is unchanged when the “derived-class” object d is

substituted for the “base-class” object b, then D is a subtype of B.

If, for each object d of type D, there exists an object b of type B such that,

for all programs P defined in terms of B, the behavior of P is unchanged

when d is substituted for b, then D is a subtype of B.

Page 282: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

282

4. Proper Inheritance

What Is Liskov Substitution?

class Bool {

bool d_v; public: Bool(int x) : d_v(x) { } operator bool() const {return d_v;} };

class Fool : public Bool {

public: Fool(int x) : Bool(!x) { } };

main()

{ Bool b0(false);

Bool b1(true);

// …

p(b0, b1, …);

}

void p(const Bool& x, const Bool& y, …) { /* … */ }

main()

{ Fool f0(false);

Fool f1(true);

// …

p(f1, f0, …);

}

If, for each object d of type D, there exists an object b of type B such that,

for all programs P defined in terms of B, the behavior of P is unchanged

when d is substituted for b, then D is a subtype of B.

Page 283: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

283

4. Proper Inheritance

What Is Liskov Substitution?

class Bool {

bool d_v; public: Bool(int x) : d_v(x) { } operator bool() const {return d_v;} };

class Fool : public Bool {

public: Fool(int x) : Bool(!x) { } };

main()

{ Bool b0(false);

Bool b1(true);

// …

p(b0, b1, …);

}

void p(const Bool& x, const Bool& y, …) { /* … */ }

main()

{ Fool f0(false);

Fool f1(true);

// …

p(f1, f0, …);

}

If, for each object d of type D, there exists an object b of type B such that,

for all programs P defined in terms of B, the behavior of P is unchanged

when d is substituted for b, then D is a subtype of B.

Page 284: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

284

4. Proper Inheritance

What Is Liskov Substitution?

class Bool {

bool d_v; public: Bool(int x) : d_v(x) { } operator bool() const {return d_v;} };

class Fool : public Bool {

public: Fool(int x) : Bool(!x) { } };

main()

{ Bool b0(false);

Bool b1(true);

// …

p(b0, b1, …);

}

void p(const Bool& x, const Bool& y, …) { /* … */ }

main()

{ Fool f0(false);

Fool f1(true);

// …

p(f1, f0, …);

}

If, for each object d of type D, there exists an object b of type B such that,

for all programs P defined in terms of B, the behavior of P is unchanged

when d is substituted for b, then D is a subtype of B.

Page 285: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

285

4. Proper Inheritance

What Is Proper Inheritance?

Recall the following general property:

For inheritance to be proper, any operation that can be invoked on a derived-class object via a base-class pointer (or reference) must behave identically if we replace that base-class pointer (or reference) with a corresponding derived-class one.

Note that this is how virtual functions behave!

Page 286: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

286

4. Proper Inheritance

What Is Proper Inheritance?

void example(Derived *pDerived)

{

Base *pBase = pDerived;

#ifdef USE_DERIVED_CLASS_INTERFACE

pDerived->someMethod(/* … */);

int result = someFunction(*pDerive);

#else

pBase->someMethod(/* … */);

int result = someFunction(*pBase);

#endif

Derived

Base

Page 287: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

287

4. Proper Inheritance

Pure Structural Inheritance #ifdef USE_BASE_CLASS_INTERFACE

typedef Point Type;

#else

typedef Pixel Type;

#endif

void anyProgram(Type *p);

void main()

{

Pixel pixel(1, 2, Pixel::BLUE);

anyProgram(&pixel);

}

using std::cout; // (We do this only

using std::endl; // in test drivers.)

Pixel

Point

Page 288: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

288

4. Proper Inheritance

Pure Structural Inheritance

Pixel

Point

void anyProgram(Type *p)

{

cout << p->x() << endl;

}

int Point::x() const

{

return d_x;

}

Page 289: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

289

4. Proper Inheritance

Pure Structural Inheritance

Pixel

Point

void anyProgram(Type *p)

{

p->setY(10);

}

void Point::setY(int y)

{

d_y = y;

}

Page 290: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

290

4. Proper Inheritance

Pure Structural Inheritance

Pixel

Point

void anyProgram(Type *p)

{

cout << p->color() << endl;

}

Pixel::Color Pixel::color() const

{

return d_color;

}

class Pixel : public Point {

// …

Color d_color;

// …

};

Page 291: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

291

4. Proper Inheritance

Pure Structural Inheritance

Pixel

Point

void anyProgram(Type *p)

{

p->setY(10);

}

void Pixel::setY(int y)

{

cout << "Pixel::setY(int y)" << endl;

d_y = y;

}

void Point::setY(int y)

{

d_y = y;

}

Page 292: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

292

4. Proper Inheritance

Pure Structural Inheritance

Pixel

Point

void anyProgram(Type *p)

{

p->setY(10);

}

void Pixel::setY(int y)

{

cout << "Pixel::setY(int y)" << endl;

d_y = y;

}

void Point::setY(int y)

{

d_y = y;

}

!

Page 293: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

293

4. Proper Inheritance

Pure Structural Inheritance

Pixel

Point

void anyProgram(Type *p)

{

p->setY(10);

}

void Pixel::setY(int y)

{

++s_numSetY; // Pixel class data

d_y = y;

}

void Point::setY(int y)

{

d_y = y;

}

class Pixel : public Point {

// …

static int s_numSetY;

public:

// …

};

Page 294: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

294

4. Proper Inheritance

Pure Structural Inheritance

Pixel

Point

void anyProgram(Type *p)

{

p->setY(10);

cout << p->numSetY() << endl;

}

void Pixel::setY(int y)

{

++s_numSetY; // Pixel class data

d_y = y;

}

int Pixel::numSetY() { return s_numSetY; }

void Point::setY(int y)

{

d_y = y;

}

class Pixel : public Point {

// …

static int s_numSetY;

public:

// …

};

Page 295: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

295

4. Proper Inheritance

Pure Structural Inheritance

Pixel

Point

void anyProgram(Type *p)

{

p->setY(10);

}

void Pixel::setY(int y)

// Set the y-coordinate of this object to the absolute value of the

// specified 'y'. The behavior is undefined unless 'INT_MIN < y'.

{

d_y = y < 0 ? -y : y;

}

void Point::setY(int y)

// Set the y-coordinate of this object to the specified 'y'.

// The behavior is undefined unless '0 <= y'.

{

d_y = y;

}

Page 296: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

296

4. Proper Inheritance

Pure Structural Inheritance

Pixel

Point

void anyProgram(Type *p)

{

if (sizeof p->self() > sizeof(Point))

cout << "It's not a Point!" << endl;

}

const Pixel& Pixel::self() const

{

return *this;

}

const Point& Point::self() const

{

return *this;

}

class Pixel : public Point {

// …

Color d_color;

// …

};

Page 297: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

297

4. Proper Inheritance

Pure Structural Inheritance

Pixel

Point

void anyProgram(Type *p)

{

if (sizeof p->self() > sizeof(Point)) ?

cout << "It's not a Point!" << endl;

}

const Pixel& Pixel::self() const

{

return *this;

}

const Point& Point::self() const

{

return *this;

}

class Pixel : public Point {

// …

Color d_color;

// …

};

Page 298: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

298

4. Proper Inheritance

Pure Structural Inheritance

Pixel

Point

void anyProgram(Type *p)

{

if (sizeof p->self() > 8) // sizeof(Point)

cout << "It's not a Point!" << endl;

}

const Pixel& Pixel::self() const

{

return *this;

}

const Point& Point::self() const

{

return *this;

}

class Pixel : public Point {

// …

Color d_color;

// …

};

Page 299: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

299

4. Proper Inheritance

Pure Structural Inheritance

Pixel

Point

void anyProgram(Type *p)

{

if (sizeof p->self() > 8) // sizeof(Point)

cout << "It's not a Point!" << endl;

}

const Pixel& Pixel::self() const

{

return *this;

}

const Point& Point::self() const

{

return *this;

}

class Pixel : public Point {

// …

Color d_color;

// …

};

Page 300: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

300

4. Proper Inheritance

Pure Structural Inheritance

Pixel

Point

void anyProgram(Type *p)

{

if (sizeof p->self() > 8) // sizeof(Point)

cout << "It's not a point!" << endl;

}

const Pixel& Pixel::self() const

{

return *this;

}

const Point& Point::self() const

{

return *this;

}

class Pixel : public Point {

// …

Color d_color;

// …

};

Page 301: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

301

4. Proper Inheritance

Pure Structural Inheritance

Pixel

Point

void anyProgram(Type *p)

{

if (sizeof p->self() > sizeof(Point))

cout << "It's not a Point!" << endl;

}

const Pixel& Pixel::self() const

{

return *this;

}

const Point& Point::self() const

{

return *this;

}

class Pixel : public Point {

// …

Color d_color;

// …

};

Page 302: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

302

4. Proper Inheritance

Pure Structural Inheritance

Pixel

Point

void anyProgram(Type *p)

{

if (sizeof p->self() > sizeof(Point))

cout << "It's not a Point!" << endl;

}

const Pixel& Pixel::self() const

{

return *this;

}

const Point& Point::self() const

{

return *this;

}

!

class Pixel : public Point {

// …

Color d_color;

// …

};

Page 303: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

303

4. Proper Inheritance

Pure Structural Inheritance

Pixel

Point

void anyProgram(Type *p)

{

if (sizeof *p > sizeof(Point))

cout << "It's not a Point!" << endl;

}

class Pixel : public Point {

// …

Color d_color;

// …

};

Page 304: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

304

4. Proper Inheritance

Pure Structural Inheritance

Pixel

Point

void anyProgram(Type *p)

{

if (sizeof *p > sizeof(Point))

cout << "It's not a Point!" << endl;

}

class Pixel : public Point {

// …

Color d_color;

// …

}; !

Page 305: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

305

4. Proper Inheritance

Pure Structural Inheritance

Pixel

Point

void anyProgram(Type *p)

{

if (sizeof *p > sizeof(Point))

cout << "It's not a Point!" << endl;

}

class Pixel : public Point {

// …

Color d_color;

// …

}; !

Page 306: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

306

4. Proper Inheritance

Pure Structural Inheritance

Pixel

Point

void anyProgram(Type *p)

{

if (sizeof *p > sizeof(Point))

cout << "It's not a Point!" << endl;

}

class Pixel : public Point {

// …

Color d_color;

// …

}; !

Proper Structural

Inheritance extends

functionality, but

does not extend the

object’s footprint.

Page 307: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

307

4. Proper Inheritance

Pure Structural Inheritance

Pixel

Point

void anyProgram(Type *p)

{

double alignmentHack; // Don’t do it!

char buffer[sizeof(Point)];

(Type *)&buffer = *p;

}

class Pixel : public Point {

// …

Color d_color;

// …

}; !

buffer

buffer

The same “size” issue applies to arrays of objects!

?!?!

Page 308: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

308

4. Proper Inheritance

Implementation Inheritance

CompositeWidget

Widget

Implementation hierarchies

are highly problematic!

Incorporating implementation with interface

inheritance: – Makes software brittle, inflexible, and hard to

maintain.

– Exposes public clients to physical (compile-

and link-time) dependencies on the shared

implementation.

– Adds nothing that cannot be done with pure

interface inheritance and layering.

Its only value is as a syntactic expedient!

Page 309: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

309

Point

Polygon Square

Rectangle

Shape

MyRectangle

Page 310: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

310

Point

Polygon Square

Rectangle

Shape

origin; width

origin; width; length

origin

origin; numVertices;

operator[](int index)

MyRectangle

x; y

Page 311: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

311

Point

Polygon Square

Rectangle

Shape

x; y

origin; width

origin; width; length

origin

?

A Rectangle

Is-A Square

with a length

attribute?

origin; numVertices;

operator[](int index)

MyRectangle

Page 312: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

312

Point

Polygon Square

Rectangle

Shape

x; y

origin; width

origin; width; length

origin

?

A Rectangle

Is-A Square

with a length

attribute?

origin; numVertices;

operator[](int index)

MyRectangle

Rectangle does not respect

Square

Invariant

Page 313: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

313

Point

Polygon Square

Rectangle

Shape

x; y

origin; width

origin; width; length

origin

?

A Rectangle

Is-A Square

with a length

attribute?

origin; numVertices;

operator[](int index)

MyRectangle

Page 314: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

314

Point

Polygon Square

Shape

Rectangle

x; y

origin; width

origin; width; length

origin

origin; numVertices;

operator[](int index)

MyRectangle

Page 315: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

315

Point

Polygon Square

Shape

Rectangle

x; y

origin; width

origin; width; length

origin

origin; numVertices;

operator[](int index)

MyRectangle

Page 316: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

316

Point

Polygon Square

Shape

Rectangle

x; y

origin; width

origin; width; length

origin

origin; numVertices;

operator[](int index)

MyRectangle

Page 317: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

317

Point

Polygon Square

Shape

Rectangle

x; y

origin; width

origin; width; length

origin

origin; numVertices;

operator[](int index)

MyRectangle

Page 318: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

318

Square

Rectangle

Page 319: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

319

Square

Rectangle void stretchBy1(Rectangle *r)

{

int wid = r->width();

int len = r->length();

r->setLength(len + 1);

assert(wid == r->width());

assert(len + 1 == r->length());

}

Page 320: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

320

Square

Rectangle void stretchBy1(Rectangle *r)

{

int wid = r->width();

int len = r->length();

r->setLength(len + 1);

assert(wid == r->width());

assert(len + 1 == r->length());

}

Page 321: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

321

Square

Rectangle void stretchBy1(Rectangle *r)

{

int wid = r->width();

int len = r->length();

r->setLength(len + 1);

assert(wid == r->width());

assert(len + 1 == r->length());

}

Page 322: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

322

Square

Rectangle void stretchBy1(Rectangle *r)

{

int wid = r->width();

int len = r->length();

r->setLength(len + 1);

assert(wid == r->width());

assert(len + 1 == r->length());

}

Page 323: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

323

Square

Rectangle void stretchBy1(Rectangle *r)

{

int wid = r->width();

int len = r->length();

r->setLength(len + 1);

assert(wid == r->width());

assert(len + 1 == r->length());

}

Page 324: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

324

Square

Rectangle void stretchBy1(Rectangle *r)

{

int wid = r->width();

int len = r->length();

r->setLength(len + 1);

assert(wid == r->width());

assert(len + 1 == r->length());

}

Page 325: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

325

Square

Rectangle void stretchBy1(Rectangle *r)

{

int wid = r->width();

int len = r->length();

r->setLength(len + 1);

assert(wid == r->width());

assert(len + 1 == r->length());

}

Page 326: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

326

Square

Rectangle void stretchBy1(Rectangle *r)

{

int wid = r->width();

int len = r->length();

r->setLength(len + 1);

assert(wid == r->width());

assert(len + 1 == r->length());

}

Either Assert

or No Longer

Square

Page 327: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

327

Square

Rectangle void stretchBy1(Rectangle *r)

{

int wid = r->width();

int len = r->length();

r->setLength(len + 1);

assert(wid == r->width());

assert(len + 1 == r->length());

}

Either Assert

or No Longer

Square

Page 328: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

328

Point

Polygon Square

Shape

Rectangle

x; y

origin; width

origin; width; length

origin

origin; numVertices;

operator[](int index)

MyRectangle

Page 329: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

329

Point

Polygon Square

Shape

Rectangle

x; y

origin; width

origin; width; length

origin

origin; numVertices;

operator[](int index)

MyRectangle

Page 330: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

330

Point

Polygon Square

Shape

Rectangle

x; y

origin; width

origin; width; length

origin

origin; numVertices;

operator[](int index)

MyRectangle

Page 331: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

331

Point

Polygon Square

Shape

Rectangle

x; y

origin; width

origin; width; length

origin

origin; numVertices;

operator[](int index)

MyRectangle

Page 332: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

332

Point

Polygon Square

Shape

Rectangle

x; y

origin; width

origin; width; length

origin

origin; numVertices;

operator[](int index)

MyRectangle

Page 333: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

333

Point

Polygon Square

Shape

Rectangle

x; y

origin; width

origin; width; length

origin

origin; numVertices;

operator[](int index)

MyRectangle

Page 334: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

334 origin() const;

(Modifiable) Rectangle

ConstShape

(Modifiable) Square

(Modifiable) Polygon

(Modifiable) Shape

(Concrete)

YourSquare (Concrete)

TheirPolygon

ConstRectangle

ConstPolygon

ConstSquare int side() const

int width() const

int length() const

Point vertex(int i) const

int numVertices() const

void setOrigin(const Point& v);

void setSide(int side)

void setWidth(int width)

void setLength(int length)

void appendVertex(const Point& v)

void removeVertex(int i)

TheirPolygon() YourSquare() MyRectangle()

(Concrete)

MyRectangle

Page 335: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

335 origin() const;

(Modifiable) Rectangle

ConstShape

(Modifiable) Square

(Modifiable) Polygon

(Modifiable) Shape

(Concrete)

YourSquare (Concrete)

TheirPolygon

ConstRectangle

ConstPolygon

ConstSquare int side() const

int width() const

int length() const

Point vertex(int i) const

int numVertices() const

void setOrigin(const Point& v);

void setSide(int side)

void setWidth(int width)

void setLength(int length)

void appendVertex(const Point& v)

void removeVertex(int i)

TheirPolygon() YourSquare() MyRectangle()

(Concrete)

MyRectangle

Page 336: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

336 origin() const;

(Modifiable) Rectangle

ConstShape

(Modifiable) Square

(Modifiable) Polygon

(Modifiable) Shape

(Concrete)

YourSquare (Concrete)

TheirPolygon

ConstRectangle

ConstPolygon

ConstSquare int side() const

int width() const

int length() const

Point vertex(int i) const

int numVertices() const

void setOrigin(const Point& v);

void setSide(int side)

void setWidth(int width)

void setLength(int length)

void appendVertex(const Point& v)

void removeVertex(int i)

TheirPolygon() YourSquare() MyRectangle()

(Concrete)

MyRectangle

Page 337: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

337 origin() const;

(Modifiable) Rectangle

ConstShape

(Modifiable) Square

(Modifiable) Polygon

(Modifiable) Shape

(Concrete)

YourSquare (Concrete)

TheirPolygon

ConstRectangle

ConstPolygon

ConstSquare int side() const

int width() const

int length() const

Point vertex(int i) const

int numVertices() const

void setOrigin(const Point& v);

void setSide(int side)

void setWidth(int width)

void setLength(int length)

void appendVertex(const Point& v)

void removeVertex(int i)

TheirPolygon() YourSquare() MyRectangle()

(Concrete)

MyRectangle

Page 338: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

338 origin() const;

(Modifiable) Rectangle

ConstShape

(Modifiable) Square

(Modifiable) Polygon

(Modifiable) Shape

(Concrete)

YourSquare (Concrete)

TheirPolygon

ConstRectangle

ConstPolygon

ConstSquare int side() const

int width() const

int length() const

Point vertex(int i) const

int numVertices() const

void setOrigin(const Point& v);

void setSide(int side)

void setWidth(int width)

void setLength(int length)

void appendVertex(const Point& v)

void removeVertex(int i)

TheirPolygon() YourSquare() MyRectangle()

(Concrete)

MyRectangle

Page 339: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

339 origin() const;

(Modifiable) Rectangle

ConstShape

(Modifiable) Square

(Modifiable) Polygon

(Modifiable) Shape

(Concrete)

YourSquare (Concrete)

TheirPolygon

ConstRectangle

ConstPolygon

ConstSquare int side() const

int width() const

int length() const

Point vertex(int i) const

int numVertices() const

void setOrigin(const Point& v);

void setSide(int side)

void setWidth(int width)

void setLength(int length)

void appendVertex(const Point& v)

void removeVertex(int i)

TheirPolygon() YourSquare() MyRectangle()

(Concrete)

MyRectangle

Page 340: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

340 origin() const;

(Modifiable) Rectangle

ConstShape

(Modifiable) Square

(Modifiable) Polygon

(Modifiable) Shape

(Concrete)

YourSquare (Concrete)

TheirPolygon

ConstRectangle

ConstPolygon

ConstSquare int side() const

int width() const

int length() const

Point vertex(int i) const

int numVertices() const

void setOrigin(const Point& v);

void setSide(int side)

void setWidth(int width)

void setLength(int length)

void appendVertex(const Point& v)

void removeVertex(int i)

TheirPolygon() YourSquare() MyRectangle()

(Concrete)

MyRectangle

Page 341: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

341 origin() const;

(Modifiable) Rectangle

ConstShape

(Modifiable) Square

(Modifiable) Polygon

(Modifiable) Shape

(Concrete)

YourSquare (Concrete)

TheirPolygon

ConstRectangle

ConstPolygon

ConstSquare int side() const

int width() const

int length() const

Point vertex(int i) const

int numVertices() const

void setOrigin(const Point& v);

void setSide(int side)

void setWidth(int width)

void setLength(int length)

void appendVertex(const Point& v)

void removeVertex(int i)

TheirPolygon() YourSquare() MyRectangle()

(Concrete)

MyRectangle

Page 342: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

342 origin() const;

(Modifiable) Rectangle

ConstShape

(Modifiable) Square

(Modifiable) Polygon

(Modifiable) Shape

(Concrete)

YourSquare (Concrete)

TheirPolygon

ConstRectangle

ConstPolygon

ConstSquare int side() const

int width() const

int length() const

Point vertex(int i) const

int numVertices() const

void setOrigin(const Point& v);

void setSide(int side)

void setWidth(int width)

void setLength(int length)

void appendVertex(const Point& v)

void removeVertex(int i)

TheirPolygon() YourSquare() MyRectangle()

(Concrete)

MyRectangle

Page 343: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

343 origin() const;

(Modifiable) Rectangle

ConstShape

(Modifiable) Square

(Modifiable) Polygon

(Modifiable) Shape

(Concrete)

YourSquare (Concrete)

TheirPolygon

ConstRectangle

ConstPolygon

ConstSquare int side() const

int width() const

int length() const

Point vertex(int i) const

int numVertices() const

void setOrigin(const Point& v);

void setSide(int side)

void setWidth(int width)

void setLength(int length)

void appendVertex(const Point& v)

void removeVertex(int i)

TheirPolygon() YourSquare() MyRectangle()

(Concrete)

MyRectangle

Page 344: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

344 origin() const;

(Modifiable) Rectangle

ConstShape

(Modifiable) Square

(Modifiable) Polygon

(Modifiable) Shape

(Concrete)

YourSquare (Concrete)

TheirPolygon

ConstRectangle

ConstPolygon

ConstSquare int side() const

int width() const

int length() const

Point vertex(int i) const

int numVertices() const

void setOrigin(const Point& v);

void setSide(int side)

void setWidth(int width)

void setLength(int length)

void appendVertex(const Point& v)

void removeVertex(int i)

TheirPolygon() YourSquare() MyRectangle()

(Concrete)

MyRectangle

Page 345: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

345 origin() const;

(Modifiable) Rectangle

ConstShape

(Modifiable) Square

(Modifiable) Polygon

(Modifiable) Shape

(Concrete)

YourSquare (Concrete)

TheirPolygon

ConstRectangle

ConstPolygon

ConstSquare int side() const

int width() const

int length() const

Point vertex(int i) const

int numVertices() const

void setOrigin(const Point& v);

void setSide(int side)

void setWidth(int width)

void setLength(int length)

void appendVertex(const Point& v)

void removeVertex(int i)

TheirPolygon() YourSquare() MyRectangle()

(Concrete)

MyRectangle

Page 346: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

346

(Concrete)

MyRectangle

origin() const;

(Modifiable) Rectangle

ConstShape

(Modifiable) Square

(Modifiable) Polygon

(Modifiable) Shape

(Concrete)

YourSquare (Concrete)

TheirPolygon

ConstRectangle

ConstPolygon

ConstSquare int side() const

int width() const

int length() const

Point vertex(int i) const

int numVertices() const

void setOrigin(const Point& v);

void setSide(int side)

void setWidth(int width)

void setLength(int length)

void appendVertex(const Point& v)

void removeVertex(int i)

TheirPolygon() YourSquare() MyRectangle()

Page 347: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

347

(Concrete)

MyRectangle

origin() const;

(Modifiable) Rectangle

ConstShape

(Modifiable) Square

(Modifiable) Polygon

(Modifiable) Shape

(Concrete)

YourSquare (Concrete)

TheirPolygon

ConstRectangle

ConstPolygon

ConstSquare int side() const

int width() const

int length() const

Point vertex(int i) const

int numVertices() const

void setOrigin(const Point& v);

void setSide(int side)

void setWidth(int width)

void setLength(int length)

void appendVertex(const Point& v)

void removeVertex(int i)

TheirPolygon() YourSquare() MyRectangle()

Page 348: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

The principal clients of Interface Inheritance

are both the

PUBLIC CLIENT

and the

DERIVED-CLASS AUTHOR.

4. Proper Inheritance

Using Interface Inheritance Effectively

348

Page 349: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

349

Channel

int write(const char *b, int n);

int read(char *b, int n);

Page 350: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

350

Channel

MyChannel

int write(const char *b, int n);

int read(char *b, int n);

Page 351: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

351

Channel

MyChannel

Client1

int write(const char *b, int n);

int read(char *b, int n);

Page 352: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

352

Channel

TimedChannel

MyChannel

Client1

int write(const char *b, int n, int t);

int read(char *b, int n, int t);

int write(const char *b, int n);

int read(char *b, int n);

Page 353: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

353

Channel

TimedChannel

MyChannel

YourTimedChannel

Client1

int write(const char *b, int n, int t);

int read(char *b, int n, int t);

int write(const char *b, int n);

int read(char *b, int n);

Page 354: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

354

Channel

TimedChannel

MyChannel

YourTimedChannel

Client2

Client1

int write(const char *b, int n, int t);

int read(char *b, int n, int t);

int write(const char *b, int n);

int read(char *b, int n);

Page 355: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

355

Channel

TimedChannel

3rd Party

Product A

MyChannel

YourTimedChannel

Client2

Client1

int write(const char *b, int n, int t);

int read(char *b, int n, int t);

int write(const char *b, int n);

int read(char *b, int n);

Page 356: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

356

Channel

TimedChannel

3rd Party

Product A

PaChannelAdapter

MyChannel

YourTimedChannel

Client2

Client1

int write(const char *b, int n, int t);

int read(char *b, int n, int t);

int write(const char *b, int n);

int read(char *b, int n);

Page 357: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

357

Channel

TimedChannel

3rd Party

Product A

PaChannelAdapter

MyChannel

YourTimedChannel

Client2

Client3

Client1

int write(const char *b, int n, int t);

int read(char *b, int n, int t);

int write(const char *b, int n);

int read(char *b, int n);

Page 358: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

358

Channel

TimedChannel

3rd Party

Product A

3rd Party

Product B

PaChannelAdapter

MyChannel

YourTimedChannel

Client2

Client3

Client1

int write(const char *b, int n, int t);

int read(char *b, int n, int t);

int write(const char *b, int n);

int read(char *b, int n);

Page 359: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

359

Channel

TimedChannel

3rd Party

Product A

3rd Party

Product B

PaChannelAdapter

PbTimedChannelAdapter

MyChannel

YourTimedChannel

Client2

Client3

Client1

int write(const char *b, int n, int t);

int read(char *b, int n, int t);

int write(const char *b, int n);

int read(char *b, int n);

Page 360: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

360

Channel

TimedChannel

3rd Party

Product A

3rd Party

Product B

PaChannelAdapter

PbTimedChannelAdapter

MyChannel

YourTimedChannel Client4

Client2

Client3

Client1

int write(const char *b, int n, int t);

int read(char *b, int n, int t);

int write(const char *b, int n);

int read(char *b, int n);

Page 361: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Interface Inheritance Effectively

361

Channel

TimedChannel

3rd Party

Product A

3rd Party

Product B

PaChannelAdapter

PbTimedChannelAdapter

MyChannel

YourTimedChannel Client4

Client2

Client5

Client3

Client1

int write(const char *b, int n, int t);

int read(char *b, int n, int t);

int write(const char *b, int n);

int read(char *b, int n);

Page 362: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Structural Inheritance Effectively

362

(Non-Modifiable)

ConstElemRef

(Modifiable)

ElemRef

Page 363: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Structural Inheritance Effectively

363

(Non-Modifiable)

ConstElemRef

template <class TYPE>

class ConstElemRef<TYPE> {

const TYPE *d_elem_p;

friend class ElemRef<TYPE>; // Note friendship

private: // Not Implemented. TBD

ConstElemRef& operator=(Const ConstElemRef&);

public:

// CREATORS

ConstElemRef(const TYPE *elem);

ConstElemRef(const ConstElemRef& ref);

~ConstElemRef();

// ACCESSORS

const TYPE& elem() const;

};

elem() ;

Page 364: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Structural Inheritance Effectively

364

(Non-Modifiable)

ConstElemRef

template <class TYPE>

class ConstElemRef<TYPE> {

const TYPE *d_elem_p;

friend class ElemRef<TYPE>; // Note friendship

private: // Not Implemented. TBD

ConstElemRef& operator=(Const ConstElemRef&);

public:

// CREATORS

ConstElemRef(const TYPE *elem);

ConstElemRef(const ConstElemRef& ref);

~ConstElemRef();

// ACCESSORS

const TYPE& elem() const;

};

elem() ;

Single Pointer Data Member

Page 365: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Structural Inheritance Effectively

365

(Non-Modifiable)

ConstElemRef

template <class TYPE>

class ConstElemRef<TYPE> {

const TYPE *d_elem_p;

friend class ElemRef<TYPE>; // Note friendship

private: // Not Implemented. TBD

ConstElemRef& operator=(Const ConstElemRef&);

public:

// CREATORS

ConstElemRef(const TYPE *elem);

ConstElemRef(const ConstElemRef& ref);

~ConstElemRef();

// ACCESSORS

const TYPE& elem() const;

};

elem() ;

Derived Class Declared Friend

Page 366: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Structural Inheritance Effectively

366

(Non-Modifiable)

ConstElemRef

template <class TYPE>

class ConstElemRef<TYPE> {

const TYPE *d_elem_p;

friend class ElemRef<TYPE>; // Note friendship

private: // Not Implemented. TBD

ConstElemRef& operator=(Const ConstElemRef&);

public:

// CREATORS

ConstElemRef(const TYPE *elem);

ConstElemRef(const ConstElemRef& ref);

~ConstElemRef();

// ACCESSORS

const TYPE& elem() const;

};

elem() ;

Copy Assignment Not Implemented

Page 367: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Structural Inheritance Effectively

367

(Non-Modifiable)

ConstElemRef

template <class TYPE>

class ConstElemRef<TYPE> {

const TYPE *d_elem_p;

friend class ElemRef<TYPE>; // Note friendship

private: // Not Implemented. TBD

ConstElemRef& operator=(Const ConstElemRef&);

public:

// CREATORS

ConstElemRef(const TYPE *elem);

ConstElemRef(const ConstElemRef& ref);

~ConstElemRef();

// ACCESSORS

const TYPE& elem() const;

};

elem() ;

Read-Only Access

Page 368: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Structural Inheritance Effectively

368

ConstElemRef

template <class TYPE>

class ElemRef<TYPE> : public ConstElemRef<TYPE> {

public:

// CREATORS

ElemRef(TYPE *elem);

ElemRef(const ElemRef& ref);

~ElemRef();

// MANIPULATORS

ElemRef& operator=(const ElemRef&); // Fine. TBD

// ACCESSORS

TYPE& elem() const;

};

(Modifiable)

ElemRef

class ConstElemRef<TYPE> {

const TYPE *d_elem_p;

// …

const TYPE& elem() const;

};

elem() ;

elem() ;

Page 369: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Structural Inheritance Effectively

369

ConstElemRef

template <class TYPE>

class ElemRef<TYPE> : public ConstElemRef<TYPE> {

public:

// CREATORS

ElemRef(TYPE *elem);

ElemRef(const ElemRef& ref);

~ElemRef();

// MANIPULATORS

ElemRef& operator=(const ElemRef&); // Fine. TBD

// ACCESSORS

TYPE& elem() const;

};

(Modifiable)

ElemRef

class ConstElemRef<TYPE> {

const TYPE *d_elem_p;

// …

const TYPE& elem() const;

};

elem() ;

elem() ;

Public Structural

Inheritance

Page 370: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Structural Inheritance Effectively

370

ConstElemRef

template <class TYPE>

class ElemRef<TYPE> : public ConstElemRef<TYPE> {

public:

// CREATORS

ElemRef(TYPE *elem);

ElemRef(const ElemRef& ref);

~ElemRef();

// MANIPULATORS

ElemRef& operator=(const ElemRef&); // Fine. TBD

// ACCESSORS

TYPE& elem() const;

};

(Modifiable)

ElemRef

class ConstElemRef<TYPE> {

const TYPE *d_elem_p;

// …

const TYPE& elem() const;

};

elem() ;

elem() ;

No Additional Member Data

Page 371: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Structural Inheritance Effectively

371

ConstElemRef

template <class TYPE>

class ElemRef<TYPE> : public ConstElemRef<TYPE> {

public:

// CREATORS

ElemRef(TYPE *elem);

ElemRef(const ElemRef& ref);

~ElemRef();

// MANIPULATORS

ElemRef& operator=(const ElemRef&); // Fine. TBD

// ACCESSORS

TYPE& elem() const;

};

(Modifiable)

ElemRef

class ConstElemRef<TYPE> {

const TYPE *d_elem_p;

// …

const TYPE& elem() const;

};

elem() ;

elem() ;

Copy Assignment Implemented

Page 372: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Structural Inheritance Effectively

372

ConstElemRef

template <class TYPE>

class ElemRef<TYPE> : public ConstElemRef<TYPE> {

public:

// CREATORS

ElemRef(TYPE *elem);

ElemRef(const ElemRef& ref);

~ElemRef();

// MANIPULATORS

ElemRef& operator=(const ElemRef&); // Fine. TBD

// ACCESSORS

TYPE& elem() const;

};

(Modifiable)

ElemRef

class ConstElemRef<TYPE> {

const TYPE *d_elem_p;

// …

const TYPE& elem() const;

};

elem() ;

elem() ;

Read-Write Access

Page 373: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Structural Inheritance Effectively

373

ConstElemRef

template <class TYPE>

class ElemRef<TYPE> : public ConstElemRef<TYPE> {

public:

// CREATORS

ElemRef(TYPE *elem);

ElemRef(const ElemRef& ref);

~ElemRef();

// MANIPULATORS

ElemRef& operator=(const ElemRef&); // Fine. TBD

// ACCESSORS

TYPE& elem() const;

};

(Modifiable)

ElemRef

class ConstElemRef<TYPE> {

const TYPE *d_elem_p;

// …

const TYPE& elem() const;

};

elem() ;

elem() ;

Read-Write Access

An ElemRef

Is-A ConstElemRef

with “Write Access”

Page 374: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Structural Inheritance Effectively

374

ConstElemRef

template <class TYPE>

class ElemRef<TYPE> : public ConstElemRef<TYPE> {

public:

// CREATORS

ElemRef(TYPE *elem);

ElemRef(const ElemRef& ref);

~ElemRef();

// MANIPULATORS

ElemRef& operator=(const ElemRef&); // Fine. TBD

// ACCESSORS

TYPE& elem() const;

};

(Modifiable)

ElemRef

class ConstElemRef<TYPE> {

const TYPE *d_elem_p;

// …

const TYPE& elem() const;

};

elem() ;

elem() ;

Read-Write Access

An std::iterator

Is-A std::const_iterator

with “Write Access”

Page 375: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Structural Inheritance Effectively

375

const TYPE& ConstElemRef::elem() const

{

return *d_elem_p;

}

TYPE& ElemRef::elem() const

{

return *const_cast<TYPE *>(d_elem_p);

}

// Note use of friendship as well.

(Non-Modifiable)

ConstElemRef

(Modifiable)

ElemRef

Note: same component due to friendship.

Page 376: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Structural Inheritance Effectively

376

const TYPE& ConstElemRef::elem() const

{

return *d_elem_p;

}

TYPE& ElemRef::elem() const

{

return *const_cast<TYPE *>(d_elem_p);

}

// Note use of friendship as well.

(Non-Modifiable)

ConstElemRef

(Modifiable)

ElemRef

Note: same component due to friendship.

Note we are casting-away const

Page 377: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Structural Inheritance Effectively

377

(Non-Modifiable)

ConstElemRef

(Modifiable)

ElemRef

Be especially careful to ensure const-correctness when const-casting is involved.

Page 378: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Structural Inheritance Effectively

378

void g(ConstElemRef *cer1, const ConstElemRef& cer2)

{ *cer1 = cer2; // Enable const-correctness violation due to slicing.

} // Assumes copy assignment is enabled on the ConstElemRef base class.

(Non-Modifiable)

ConstElemRef

(Modifiable)

ElemRef

Be especially careful to ensure const-correctness when const-casting is involved.

Page 379: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

template < class TYPE>

void f(const TYPE& constElem)

{

TYPE dummy;

ElemRef er(&dummy);

ConstElemRef cer(&constElem);

g(&er, cer); // Rebind (modifiable) 'ElemRef' 'er'.

er.elem() = TYPE(); // Clobber 'constElem'.

4. Proper Inheritance

Using Structural Inheritance Effectively

379

void g(ConstElemRef *cer1, const ConstElemRef& cer2)

{ *cer1 = cer2; // Enable const-correctness violation due to slicing.

} // Assumes copy assignment is enabled on the ConstElemRef base class.

(Non-Modifiable)

ConstElemRef

(Modifiable)

ElemRef

Be especially careful to ensure const-correctness when const-casting is involved.

Page 380: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

template < class TYPE>

void f(const TYPE& constElem)

{

TYPE dummy;

ElemRef er(&dummy);

ConstElemRef cer(&constElem);

g(&er, cer); // Rebind (modifiable) 'ElemRef' 'er'.

er.elem() = TYPE(); // Clobber 'constElem'.

4. Proper Inheritance

Using Structural Inheritance Effectively

380

void g(ConstElemRef *cer1, const ConstElemRef& cer2)

{ *cer1 = cer2; // Enable const-correctness violation due to slicing.

} // Assumes copy assignment is enabled on the ConstElemRef base class.

(Non-Modifiable)

ConstElemRef

(Modifiable)

ElemRef

Be especially careful to ensure const-correctness when const-casting is involved.

Page 381: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

template < class TYPE>

void f(const TYPE& constElem)

{

TYPE dummy;

ElemRef er(&dummy);

ConstElemRef cer(&constElem);

g(&er, cer); // Rebind (modifiable) 'ElemRef' 'er'.

er.elem() = TYPE(); // Clobber 'constElem'.

4. Proper Inheritance

Using Structural Inheritance Effectively

381

void g(ConstElemRef *cer1, const ConstElemRef& cer2)

{ *cer1 = cer2; // Enable const-correctness violation due to slicing.

} // Assumes copy assignment is enabled on the ConstElemRef base class.

(Non-Modifiable)

ConstElemRef

(Modifiable)

ElemRef

Be especially careful to ensure const-correctness when const-casting is involved.

Page 382: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

template < class TYPE>

void f(const TYPE& constElem)

{

TYPE dummy;

ElemRef er(&dummy);

ConstElemRef cer(&constElem);

g(&er, cer); // Rebind (modifiable) 'ElemRef' 'er'.

er.elem() = TYPE(); // Clobber 'constElem'.

4. Proper Inheritance

Using Structural Inheritance Effectively

382

void g(ConstElemRef *cer1, const ConstElemRef& cer2)

{ *cer1 = cer2; // Enable const-correctness violation due to slicing.

} // Assumes copy assignment is enabled on the ConstElemRef base class.

(Non-Modifiable)

ConstElemRef

(Modifiable)

ElemRef

Be especially careful to ensure const-correctness when const-casting is involved.

Page 383: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

template < class TYPE>

void f(const TYPE& constElem)

{

TYPE dummy;

ElemRef er(&dummy);

ConstElemRef cer(&constElem);

g(&er, cer); // Rebind (modifiable) 'ElemRef' 'er'.

er.elem() = TYPE(); // Clobber 'constElem'.

4. Proper Inheritance

Using Structural Inheritance Effectively

383

void g(ConstElemRef *cer1, const ConstElemRef& cer2)

{ *cer1 = cer2; // Enable const-correctness violation due to slicing.

} // Assumes copy assignment is enabled on the ConstElemRef base class.

(Non-Modifiable)

ConstElemRef

(Modifiable)

ElemRef

Be especially careful to ensure const-correctness when const-casting is involved.

Page 384: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

template < class TYPE>

void f(const TYPE& constElem)

{

TYPE dummy;

ElemRef er(&dummy);

ConstElemRef cer(&constElem);

g(&er, cer); // Rebind (modifiable) 'ElemRef' 'er'.

er.elem() = TYPE(); // Clobber 'constElem'.

4. Proper Inheritance

Using Structural Inheritance Effectively

384

void g(ConstElemRef *cer1, const ConstElemRef& cer2)

{ *cer1 = cer2; // Enable const-correctness violation due to slicing.

} // Assumes copy assignment is enabled on the ConstElemRef base class.

(Non-Modifiable)

ConstElemRef

(Modifiable)

ElemRef

Be especially careful to ensure const-correctness when const-casting is involved.

Page 385: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Structural Inheritance Effectively

385

The principal client of Structural Inheritance

is the

PUBLIC CLIENT.

Page 386: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Structural Inheritance Effectively

386

ConstElemRefClient

(Non-Modifiable)

ConstElemRef

(Modifiable)

ElemRef

ElemRefClient

Note: No Runtime-Performance

Overhead (e.g., due to Dynamic

Binding).

Page 387: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Implementation Inheritance Effectively

387

CompositeWidget

Widget

instanceName origin move draw numChildren addChild removeChild

WidgetClient

Page 388: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Implementation Inheritance Effectively

388

CompositeWidget

Widget

instanceName origin move draw

numChildren addChild removeChild

WidgetClient

CompositeWidgetClient

Page 389: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Implementation Inheritance Effectively

389

CompositeWidget

Widget

instanceName origin move draw

numChildren addChild removeChild

WidgetClient

CompositeWidgetClient

MyWidget

Page 390: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Implementation Inheritance Effectively

390

CompositeWidget

WidgetImp

numChildren addChild removeChild

WidgetClient

CompositeWidgetClient

instanceName origin move draw

Widget

MyWidget

Page 391: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Implementation Inheritance Effectively

391

CompositeWidget

WidgetImp

numChildren addChild removeChild

WidgetClient

CompositeWidgetClient

instanceName origin move draw

Widget

MyWidget

YourWidget

Page 392: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

392

CompositeWidget

WidgetImp

numChildren addChild removeChild

WidgetClient

CompositeWidgetClient

instanceName origin move draw

Widget

MyWidget

YourWidget

MyCompositeWidget

4. Proper Inheritance

Using Implementation Inheritance Effectively

Page 393: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Implementation Inheritance Effectively

393

WidgetImp

numChildren addChild removeChild

WidgetClient

CompositeWidgetClient

instanceName origin move draw

Widget

MyWidget

YourWidget

CompositeWidget

CompositeWidgetImp

MyCompositeWidget

Page 394: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Implementation Inheritance Effectively

394

WidgetImp

numChildren addChild removeChild

WidgetClient

CompositeWidgetClient

instanceName origin move draw

Widget

MyWidget

YourWidget

CompositeWidget

CompositeWidgetImp

MyCompositeWidget

YourCompositeWidget

Page 395: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Implementation Inheritance Effectively

395

WidgetImp

numChildren addChild removeChild

WidgetClient

CompositeWidgetClient

instanceName origin move draw

Widget

MyWidget

YourWidget

CompositeWidget

CompositeWidgetImp

MyCompositeWidget

YourCompositeWidget

Page 396: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Implementation Inheritance Effectively

396

WidgetImp

numChildren addChild removeChild

WidgetClient

CompositeWidgetClient

instanceName origin move draw

Widget

MyWidget

YourWidget

CompositeWidget

CompositeWidgetImp

MyCompositeWidget

YourCompositeWidget

Page 397: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Implementation Inheritance Effectively

397

WidgetImp

numChildren addChild removeChild

WidgetClient

CompositeWidgetClient

instanceName origin move draw

Widget

MyWidget

YourWidget

CompositeWidget

CompositeWidgetImp

MyCompositeWidget

YourCompositeWidget

Page 398: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Implementation Inheritance Effectively

398

WidgetImp

numChildren addChild removeChild

WidgetClient

CompositeWidgetClient

instanceName origin move draw

Widget

MyWidget

YourWidget

CompositeWidget

CompositeWidgetImp

MyCompositeWidget

YourCompositeWidget

Page 399: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Implementation Inheritance Effectively

399

WidgetImp

numChildren addChild removeChild

WidgetClient

CompositeWidgetClient

instanceName origin move draw

Widget

MyWidget

YourWidget

CompositeWidget

CompositeWidgetImp

MyCompositeWidget

YourCompositeWidget

Page 400: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Implementation Inheritance Effectively

400

WidgetImp

numChildren addChild removeChild

WidgetClient

CompositeWidgetClient

instanceName origin move draw

Widget

MyWidget

YourWidget

CompositeWidget

CompositeWidgetImp

MyCompositeWidget

YourCompositeWidget

Page 401: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Implementation Inheritance Effectively

401

WidgetImp

numChildren addChild removeChild

WidgetClient

CompositeWidgetClient

instanceName origin move draw

Widget

MyWidget

YourWidget

CompositeWidget

CompositeWidgetImp

MyCompositeWidget

YourCompositeWidget

Widen interface

first;

Page 402: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Implementation Inheritance Effectively

402

WidgetImp

numChildren addChild removeChild

WidgetClient

CompositeWidgetClient

instanceName origin move draw

Widget

MyWidget

YourWidget

CompositeWidget

CompositeWidgetImp

MyCompositeWidget

YourCompositeWidget

Widen interface

first; then provide

implementation

without widening.

Page 403: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Implementation Inheritance Effectively

403

The principal client of Implementation Inheritance

is the

DERIVED-CLASS AUTHOR.

Page 404: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Implementation Inheritance Effectively

404

Widget

CompositeWidget

numChildren addChild removeChild

instanceName origin move draw

Page 405: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Implementation Inheritance Effectively

405 Framework

Part of Framework using CompositeWidget

Part of Framework using Widget

Widget

CompositeWidget

numChildren addChild removeChild

instanceName origin move draw

Page 406: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Implementation Inheritance Effectively

406 Framework

Part of Framework using CompositeWidget

Part of Framework using Widget

Widget

CompositeWidget

numChildren addChild removeChild

instanceName origin move draw

Page 407: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Implementation Inheritance Effectively

407

WidgetPartialImp

Framework

Part of Framework using CompositeWidget

Part of Framework using Widget

Widget

CompositeWidget

numChildren addChild removeChild

instanceName origin move draw

Page 408: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Implementation Inheritance Effectively

408

WidgetPartialImp

CompositeWidgetPartialImp

Framework

Part of Framework using CompositeWidget

Part of Framework using Widget

Widget

CompositeWidget

numChildren addChild removeChild

instanceName origin move draw

Page 409: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Implementation Inheritance Effectively

409

WidgetPartialImp

CompositeWidgetPartialImp

MyWidget

Framework

Part of Framework using CompositeWidget

Part of Framework using Widget

Widget

CompositeWidget

numChildren addChild removeChild

instanceName origin move draw

Page 410: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Implementation Inheritance Effectively

410

WidgetPartialImp

CompositeWidgetPartialImp

MyCompositeWidget

MyWidget

Framework

Part of Framework using CompositeWidget

Part of Framework using Widget

Widget

CompositeWidget

numChildren addChild removeChild

instanceName origin move draw

Page 411: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Implementation Inheritance Effectively

411

WidgetPartialImp

CompositeWidgetPartialImp

MyCompositeWidget YourWidget

MyWidget

Framework

Part of Framework using CompositeWidget

Part of Framework using Widget

Widget

CompositeWidget

numChildren addChild removeChild

instanceName origin move draw

Page 412: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Implementation Inheritance Effectively

412

WidgetPartialImp

CompositeWidgetPartialImp

YourCompositeWidget

MyCompositeWidget YourWidget

MyWidget

Framework

Part of Framework using CompositeWidget

Part of Framework using Widget

Widget

CompositeWidget

numChildren addChild removeChild

instanceName origin move draw

Page 413: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Implementation Inheritance Effectively

413

WidgetPartialImp

CompositeWidgetPartialImp

YourCompositeWidget

MyCompositeWidget YourWidget

TheirCompositeWidget MyWidget

Framework

Part of Framework using CompositeWidget

Part of Framework using Widget

Widget

CompositeWidget

numChildren addChild removeChild

instanceName origin move draw

Page 414: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

4. Proper Inheritance

Using Implementation Inheritance Effectively

414

WidgetPartialImp

CompositeWidgetPartialImp

YourCompositeWidget

MyCompositeWidget YourWidget

TheirCompositeWidget MyWidget

TheirWidget

Framework

Part of Framework using CompositeWidget

Part of Framework using Widget

Widget

CompositeWidget

numChildren addChild removeChild

instanceName origin move draw

Page 415: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

415

4. Proper Inheritance

Combining Kinds of Inheritance

Page 416: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

416

4. Proper Inheritance

Combining Kinds of Inheritance • Structural & Interface

Page 417: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

417

4. Proper Inheritance

Combining Kinds of Inheritance • Structural & Interface

–Typically for Efficiency and Syntactic Sugar.

Page 418: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

418

4. Proper Inheritance

Combining Kinds of Inheritance • Structural & Interface

–Typically for Efficiency and Syntactic Sugar.

• Interface & Implementation

Page 419: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

419

4. Proper Inheritance

Combining Kinds of Inheritance • Structural & Interface

–Typically for Efficiency and Syntactic Sugar.

• Interface & Implementation –Interface inheritance (widening) first; then

implementation inheritance (no widening) .

Page 420: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

420

4. Proper Inheritance

Combining Kinds of Inheritance • Structural & Interface

–Typically for Efficiency and Syntactic Sugar.

• Interface & Implementation –Interface inheritance (widening) first; then

implementation inheritance (no widening) .

• Implementation & Structural

Page 421: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

421

4. Proper Inheritance

Combining Kinds of Inheritance • Structural & Interface

–Typically for Efficiency and Syntactic Sugar.

• Interface & Implementation –Interface inheritance (widening) first; then

implementation inheritance (no widening) .

• Implementation & Structural –Bad Idea: Unnecessarily addresses the

needs of derived class authors and public clients in the same physical component.

Page 422: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

422

4. Proper Inheritance

Combining Kinds of Inheritance

inline int f(); virtual void g() = 0; virtual void h() = 0;

Public

Client

virtual void g();

virtual void g() { } virtual void h() { }

Page 423: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

423

4. Proper Inheritance

Combining Kinds of Inheritance

inline int f(); virtual void g(); virtual void h();

virtual void g();

Public

Client

Page 424: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

424

4. Proper Inheritance

Combining Kinds of Inheritance

inline int f(); virtual void g(); virtual void h();

virtual void g();

Public

Client

Page 425: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

425

4. Proper Inheritance

Combining Kinds of Inheritance

inline int f(); virtual void g(); virtual void h();

virtual void g();

Public

Client

Page 426: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

426

4. Proper Inheritance

Relative Utility Interface Inheritance

Structural Inheritance

Implementation Inheritance

Page 427: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

427

4. Proper Inheritance

Physical Substitutability

Page 428: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

428

4. Proper Inheritance

Physical Substitutability

Page 429: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

429

4. Proper Inheritance

Physical Substitutability

Page 430: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

430

4. Proper Inheritance

Physical Substitutability

What Criteria Must Be Satisfied?

Page 431: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

431

4. Proper Inheritance

Physical Substitutability

The new component’s logical behavior:

Page 432: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

432

4. Proper Inheritance

Physical Substitutability

The new component’s logical behavior:

• Preconditions needed for defined behavior can be made weaker, but no stronger.

Page 433: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

433

4. Proper Inheritance

Physical Substitutability

The new component’s logical behavior:

• Preconditions needed for defined behavior can be made weaker, but no stronger.

• Pre-existing essential behavior of the component must remain unchanged.

Page 434: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

434

4. Proper Inheritance

Physical Substitutability

The new component’s logical behavior:

• Preconditions needed for defined behavior can be made weaker, but no stronger.

• Pre-existing essential behavior of the component must remain unchanged.

• New behaviors may be defined, and essential ones extended, so long as the component is backward compatible with pre-existing clients.

Page 435: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

435

4. Proper Inheritance

Physical Substitutability

The new component’s physical characteristics:

Page 436: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

436

4. Proper Inheritance

Physical Substitutability

The new component’s physical characteristics:

• Physical dependencies cannot increase (much).

Page 437: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

437

4. Proper Inheritance

Physical Substitutability

The new component’s physical characteristics:

• Physical dependencies cannot increase (much).

• Compile-time cannot increase substantially.

Page 438: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

438

4. Proper Inheritance

Physical Substitutability

The new component’s physical characteristics:

• Physical dependencies cannot increase (much).

• Compile-time cannot increase substantially.

• Size (footprint) cannot increase (much).

Page 439: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

439

4. Proper Inheritance

Physical Substitutability

The new component’s physical characteristics:

• Physical dependencies cannot increase (much).

• Compile-time cannot increase substantially.

• Size (footprint) cannot increase (much).

• Dynamic memory usage can’t increase (much).

Page 440: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

440

4. Proper Inheritance

Physical Substitutability

The new component’s physical characteristics:

• Physical dependencies cannot increase (much).

• Compile-time cannot increase substantially.

• Size (footprint) cannot increase (much).

• Dynamic memory usage can’t increase (much).

• Can’t introduce dynamic memory allocation.

Page 441: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

441

4. Proper Inheritance

Physical Substitutability

The new component’s physical characteristics:

• Physical dependencies cannot increase (much).

• Compile-time cannot increase substantially.

• Size (footprint) cannot increase (much).

• Dynamic memory usage can’t increase (much).

• Can’t introduce dynamic memory allocation.

• Runtime must not be increased significantly for important (relevant) use-cases.

Page 442: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

442

4. Proper Inheritance

End of Section

Questions?

Page 443: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

443

4. Proper Inheritance

What Questions are we Answering? • What distinguishes Interface, Structural, and

Implementation inheritance?

• What do we mean by the Is-A relationship, & how does proper inheritance vary from one form to the next. – What does LSP (Liskov Substitution Principle) have to do with it?

• How are each of the three inheritances used effectively? – Who is the principal client of each kind of inheritance?

– How are interface and implementation inheritance ordered?

– Does it make sense to combine two (or all three) inheritances?

– What is the relative utility of the three forms of inheritance?

• How are structural inheritance, (logical) substitutability, & backward compatibility of (physical) components related?

Page 444: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

444

Outline

1. Components (review)

Modularity, Logical/Physical Dependencies, & Level numbers

2. Interfaces and Contracts (review)

Syntax versus Semantics & Essential Behavior

3. Narrow versus Wide Contracts (review)

The Significance of Undefined Behavior

4. Proper Inheritance Is-A for Interface, Structural, & Implementation Inheritance

Page 445: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

445

1. Components (review)

Modularity, Logical/Physical Dependencies, & Level numbers

Conclusion

Page 446: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

446

1. Components (review)

Modularity, Logical/Physical Dependencies, & Level numbers

• A Component – a .h/.cpp pair satisfying four essential properties – is our fundamental unit of both logical and physical software design.

Conclusion

Page 447: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

447

1. Components (review)

Modularity, Logical/Physical Dependencies, & Level numbers

• A Component – a .h/.cpp pair satisfying four essential properties – is our fundamental unit of both logical and physical software design.

• Logical relationships, such as Is-A and Uses between classes, imply physical dependencies among the components that defined them.

Conclusion

Page 448: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

448

1. Components (review)

Modularity, Logical/Physical Dependencies, & Level numbers

• A Component – a .h/.cpp pair satisfying four essential properties – is our fundamental unit of both logical and physical software design.

• Logical relationships, such as Is-A and Uses between classes, imply physical dependencies among the components that defined them.

• No cyclic dependencies / long-distance friendships!

Conclusion

Page 449: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

449

2. Interfaces and Contracts (review)

Syntax versus Semantics & Essential Behavior

Conclusion

Page 450: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

450

2. Interfaces and Contracts (review)

Syntax versus Semantics & Essential Behavior

• An interface is syntactic; a contract is semantic.

Conclusion

Page 451: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

451

2. Interfaces and Contracts (review)

Syntax versus Semantics & Essential Behavior

• An interface is syntactic; a contract is semantic. • A contract defines both pre- & postconditions.

Conclusion

Page 452: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

452

2. Interfaces and Contracts (review)

Syntax versus Semantics & Essential Behavior

• An interface is syntactic; a contract is semantic. • A contract defines both pre- & postconditions.

• Undefined Behavior if a precondition isn’t met.

Conclusion

Page 453: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

453

2. Interfaces and Contracts (review)

Syntax versus Semantics & Essential Behavior

• An interface is syntactic; a contract is semantic. • A contract defines both pre- & postconditions.

• Undefined Behavior if a precondition isn’t met. • What undefined behavior does is undefined!

Conclusion

Page 454: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

454

2. Interfaces and Contracts (review)

Syntax versus Semantics & Essential Behavior

• An interface is syntactic; a contract is semantic. • A contract defines both pre- & postconditions.

• Undefined Behavior if a precondition isn’t met. • What undefined behavior does is undefined! • Documented essential behavior must not change!

Conclusion

Page 455: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

455

2. Interfaces and Contracts (review)

Syntax versus Semantics & Essential Behavior

• An interface is syntactic; a contract is semantic. • A contract defines both pre- & postconditions.

• Undefined Behavior if a precondition isn’t met. • What undefined behavior does is undefined! • Documented essential behavior must not change!

• Test drivers must verify all essential behavior.

Conclusion

Page 456: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

456

2. Interfaces and Contracts (review)

Syntax versus Semantics & Essential Behavior

• An interface is syntactic; a contract is semantic. • A contract defines both pre- & postconditions.

• Undefined Behavior if a precondition isn’t met. • What undefined behavior does is undefined! • Documented essential behavior must not change!

• Test drivers must verify all essential behavior. • Assertions in destructors help verify invariants.

Conclusion

Page 457: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

457

3. Narrow versus Wide Contracts (review)

The Significance of Undefined Behavior

Conclusion

Page 458: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

458

3. Narrow versus Wide Contracts (review)

The Significance of Undefined Behavior

• Narrow contracts admit undefined behavior.

Conclusion

Page 459: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

459

3. Narrow versus Wide Contracts (review)

The Significance of Undefined Behavior

• Narrow contracts admit undefined behavior.

• Appropriately narrow contracts are GOOD:

Conclusion

Page 460: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

460

3. Narrow versus Wide Contracts (review)

The Significance of Undefined Behavior

• Narrow contracts admit undefined behavior.

• Appropriately narrow contracts are GOOD:

– Reduce costs associated with development/testing

Conclusion

Page 461: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

461

3. Narrow versus Wide Contracts (review)

The Significance of Undefined Behavior

• Narrow contracts admit undefined behavior.

• Appropriately narrow contracts are GOOD:

– Reduce costs associated with development/testing

– Improve performance and reduces object-code size

Conclusion

Page 462: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

462

3. Narrow versus Wide Contracts (review)

The Significance of Undefined Behavior

• Narrow contracts admit undefined behavior.

• Appropriately narrow contracts are GOOD:

– Reduce costs associated with development/testing

– Improve performance and reduces object-code size

– Allow useful behavior to be added as needed

Conclusion

Page 463: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

463

3. Narrow versus Wide Contracts (review)

The Significance of Undefined Behavior

• Narrow contracts admit undefined behavior.

• Appropriately narrow contracts are GOOD:

– Reduce costs associated with development/testing

– Improve performance and reduces object-code size

– Allow useful behavior to be added as needed

– Enable practical/effective Defensive Programming

Conclusion

Page 464: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

464

3. Narrow versus Wide Contracts (review)

The Significance of Undefined Behavior

• Narrow contracts admit undefined behavior.

• Appropriately narrow contracts are GOOD:

– Reduce costs associated with development/testing

– Improve performance and reduces object-code size

– Allow useful behavior to be added as needed

– Enable practical/effective Defensive Programming

• Defensive programming means fault intolerance!

Conclusion

Page 465: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

465

Conclusion

4. Proper Inheritance Is-A for Interface, Structural, & Implementation Inheritance

Page 466: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

466

4. Proper Inheritance Is-A for Interface, Structural, & Implementation Inheritance

• The derived class must adhere to both contracts.

Conclusion

Page 467: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

467

4. Proper Inheritance Is-A for Interface, Structural, & Implementation Inheritance

• The derived class must adhere to both contracts.

• The static type of the pointer/reference should make no difference in programmatic behavior.

Conclusion

Page 468: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

468

4. Proper Inheritance Is-A for Interface, Structural, & Implementation Inheritance

• The derived class must adhere to both contracts.

• The static type of the pointer/reference should make no difference in programmatic behavior.

• Interface inheritance is (virtually :-) all we need!

Conclusion

Page 469: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

469

4. Proper Inheritance Is-A for Interface, Structural, & Implementation Inheritance

• The derived class must adhere to both contracts.

• The static type of the pointer/reference should make no difference in programmatic behavior.

• Interface inheritance is (virtually :-) all we need!

• Backward compatibility for components is a whole lot like proper structural inheritance.

Conclusion

Page 470: Toward a Common Intuition and Reusable Testing Methodology€¦ · 1. The .cpp file includes its .h file as the first substantive line of code. 2. All logical constructs having external

470

Conclusion

The End