23
14: Inheritance & Composition 김동원 김동원 김동원 김동원 2003.05.19

14: Inheritance & Composition

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

Page 1: 14: Inheritance & Composition

14: Inheritance & Composition

김동원김동원김동원김동원

2003.05.19

Page 2: 14: Inheritance & Composition

Thinking in C++ Page 1

Overview

• Operator overloading & inheritance

• Multiple inheritance

• Upcasting

Page 3: 14: Inheritance & Composition

Thinking in C++ Page 2

Operator overloading & inheritance

• Operator overloading & inheritance

Page 4: 14: Inheritance & Composition

Thinking in C++ Page 3

Operator overloading & inheritance

• Except for the assignment operator, operators are automatically inherited into a derived class

Page 5: 14: Inheritance & Composition

Thinking in C++ Page 4

Operator overloading & inheritance (example)

//: C14:OperatorInheritance.cpp

// Inheriting overloaded operators

#include "../C12/Byte.h"

#include <fstream>

using namespace std;

ofstream out("ByteTest.out");

class Byte2 : public Byte {

public:

// Constructors don't inherit:

Byte2(unsigned char bb = 0) : Byte(bb) {}

// operator= does not inherit, but

// is synthesized for memberwise assignment.

// However, only the SameType = SameType

// operator= is synthesized, so you have to

// make the others explicitly:

Page 6: 14: Inheritance & Composition

Thinking in C++ Page 5

Operator overloading & inheritance (example)

Byte2& operator=(const Byte& right)

{

Byte::operator=(right);

return *this;

}

Byte2& operator=(int i)

{

Byte::operator=(i);

return *this;

}

};

Page 7: 14: Inheritance & Composition

Thinking in C++ Page 6

Operator overloading & inheritance (example)

// Similar test function as in C12:ByteTest.cpp:

void k(Byte2& b1, Byte2& b2)

{

b1 = b1 * b2 + b2 % b1;

#define TRY2(OP) \

out << "b1 = "; b1.print(out); \

out << ", b2 = "; b2.print(out); \

out << "; b1 " #OP " b2 produces "; \

(b1 OP b2).print(out); \

out << endl;

b1 = 9; b2 = 47;

TRY2(+) TRY2(-) TRY2(*) TRY2(/)

TRY2(%) TRY2(^) TRY2(&) TRY2(|)

TRY2(<<) TRY2(>>) TRY2(+=) TRY2(-=)

TRY2(*=) TRY2(/=) TRY2(%=) TRY2(^=)

TRY2(&=) TRY2(|=) TRY2(>>=) TRY2(<<=)

TRY2(=) // Assignment operator

Page 8: 14: Inheritance & Composition

Thinking in C++ Page 7

Operator overloading & inheritance (example)

// Conditionals:

#define TRYC2(OP) \

out << "b1 = "; b1.print(out); \

out << ", b2 = "; b2.print(out); \

out << "; b1 " #OP " b2 produces "; \

out << (b1 OP b2); \

out << endl;

b1 = 9; b2 = 47;

TRYC2(<) TRYC2(>) TRYC2(==) TRYC2(!=) TRYC2(<=)

TRYC2(>=) TRYC2(&&) TRYC2(||)

// Chained assignment:

Byte2 b3 = 92;

b1 = b2 = b3;

}

Page 9: 14: Inheritance & Composition

Thinking in C++ Page 8

Multiple inheritance

• Multiple inheritance

Page 10: 14: Inheritance & Composition

Thinking in C++ Page 9

Multiple inheritance

• You can inherit from one class, so it would seem to make sense to inherit from more than one class at a time

• You shouldn’t try this until you’ve been programming quite a while and understand the language thoroughly

• Multiple inheritance seems simple enough

–However, multiple inheritance introduces a number of possibilities for ambiguity, which is why a chapter in Volume 2 is devoted to the subject

Page 11: 14: Inheritance & Composition

Thinking in C++ Page 10

Upcasting

• Upcasting

• Why “upcasting?”

• Upcasting and the copy constructor

• Pointer & reference upcasting

• A crisis

Page 12: 14: Inheritance & Composition

Thinking in C++ Page 11

Upcasting

• The most important aspect of inheritance

– the relationship expressed between the new class and the base class

–This relationship can be summarized by saying, “The new class is a type of the existing class”

Page 13: 14: Inheritance & Composition

Thinking in C++ Page 12

Upcasting (example)

//: C14:Instrument.cpp

// Inheritance & upcasting

enum note { middleC, Csharp, Cflat }; // Etc.

class Instrument {

public:

void play(note) const {}

};

// Wind objects are Instruments

// because they have the same interface:

class Wind : public Instrument {};

void tune(Instrument& i)

{

i.play(middleC);

}

int main()

{

Wind flute;

tune(flute); // Upcasting

} ///:~

Page 14: 14: Inheritance & Composition

Thinking in C++ Page 13

Why “upcasting?”

• Casting from derived to base moves up on the inheritance diagram, so it’s commonly referred to as upcasting

Page 15: 14: Inheritance & Composition

Thinking in C++ Page 14

Upcasting and the copy-constructor

• If you allow the compiler to synthesize a copy-constructor for a derived class, it will automatically call the base-class copy constructor, and then the copy-constructors for all the member objects

Page 16: 14: Inheritance & Composition

Thinking in C++ Page 15

Upcasting and the copy-constructor (example)

//: C14:CopyConstructor.cpp

// Correctly creating the copy-constructor

#include <iostream>

using namespace std;

class Parent {

int i;

public:

Parent(int ii) : i(ii)

{

cout << "Parent(int ii)\n";

}

Parent(const Parent& b) : i(b.i)

{

cout << "Parent(const Parent&)\n";

}

Parent() : i(0) { cout << "Parent()\n"; }

Page 17: 14: Inheritance & Composition

Thinking in C++ Page 16

Upcasting and the copy-constructor (example)

friend ostream& operator<<(ostream& os, const Parent& b)

{

return os << "Parent: " << b.i << endl;

}

};

class Member {

int i;

public:

Member(int ii) : i(ii)

{

cout << "Member(int ii)\n";

}

Member(const Member& m) : i(m.i)

{

cout << "Member(const Member&)\n";

}

Page 18: 14: Inheritance & Composition

Thinking in C++ Page 17

Upcasting and the copy-constructor (example)

friend ostream& operator<<(ostream& os, const Member& m)

{

return os << "Member: " << m.i << endl;

}

};

class Child : public Parent {

int i;

Member m;

public:

Child(int ii) : Parent(ii), i(ii), m(ii)

{

cout << "Child(int ii)\n";

}

friend ostream& operator<<(ostream& os, const Child& c)

{

return os << (Parent&)c << c.m << "Child: " << c.i << endl;

}

};

Page 19: 14: Inheritance & Composition

Thinking in C++ Page 18

Upcasting and the copy-constructor (example)

int main()

{

Child c(2);

cout << "calling copy-constructor: " << endl;

Child c2 = c; // Calls copy-constructor

cout << "values in c2:\n" << c2;

} ///:~

Page 20: 14: Inheritance & Composition

Thinking in C++ Page 19

Upcasting and the copy-constructor (example)

• Result

Parent(int ii)

Member(int ii)

Child(int ii)

calling copy-constructor:

Parent(const Parent&)

Member(const Member&)

values in c2:

Parent: 2

Member: 2

Child: 2

• If you try to write your own copy-constructor for Child then the default constructor will automatically be called for the base-class part of Child

• Child(const Child& c) : i(c.i), m(c.m) {}

Page 21: 14: Inheritance & Composition

Thinking in C++ Page 20

Upcasting and the copy-constructor (example)

• ResultParent(int ii)

Member(int ii)

Child(int ii)

calling copy-constructor:

Parent()

Member(const Member&)

values in c2:

Parent: 0

Member: 2

Child: 2

• If you try to write your own copy-constructor for Child then the default constructor will automatically be called for the base-class part of Child

• Child(const Child& c) : i(c.i), m(c.m) {}

Page 22: 14: Inheritance & Composition

Thinking in C++ Page 21

Pointer & reference upcasting

• upcasting

–occurs during the function call

– can also occur during a simple assignment to a pointer or reference

• ex)

–Wind w;

–Instrument* ip = &w; // Upcast

–Instrument& ir = w; // Upcast

Page 23: 14: Inheritance & Composition

Thinking in C++ Page 22

A crisis

• upcast loses type information about an object

–Wind w;

–Instrument* ip = &w;

� The compiler can deal with ip only as an Instrument pointer and nothing else

– It cannot know that ip actually happens to point to a Wind object