CS 330 Lecture 34 – Issues of Inheritance
Agenda
- what ?s
- program this
- weak encapsulation
- composition
- multiple inheritance?
- directed super
- the dreaded diamond problem
TODO
- Read the first three pages of http://mislav.uniqpath.com/poignant-guide/. Quarter sheet.
Program This
Given this implementation of class Rectangle:
class Rectangle {
public:
Rectangle(int w, int h) : w(w), h(h) {}
int GetWidth() const {return w;}
int GetHeight() const {return h;}
void SetWidth(int w) {this->w = w;}
void SetHeight(int h) {this->h = h;}
private:
int w, h;
}
Write a Square class.
Code
rect.cpp
#include <iostream>
class Rectangle {
public:
Rectangle(int w, int h) : w(w), h(h) {}
int GetWidth() const {return w;}
int GetHeight() const {return h;}
virtual void SetWidth(int w) {this->w = w;}
virtual void SetHeight(int h) {this->h = h;}
private:
int w, h;
}
class Square : public Rectangle {
public:
Square(int w) : Rectangle(w, w) {}
void SetWidth(int w) {Rectangle::SetWidth(w); Rectangle::SetHeight(w);}
void SetHeight(int h) {SetWidth(w);}
private:
};
int main(int argc, char **argv) {
return 0;
}
raffle.cpp
#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
using namespace std;
class Raffle {
public:
void add(const string &name);
string pick();
private:
vector<string> names;
};
void Raffle::add(const string &name) {
names.push_back(name);
}
string Raffle::pick() {
int random_unpredictable_whoknows_number = (int) (rand() / (float) RAND_MAX * (names.size() - 1));
string name = names[random_unpredictable_whoknows_number];
names.erase(names.begin() + random_unpredictable_whoknows_number);
return name;
}
int main(int argc, char **argv) {
srand(time(NULL));
Raffle raffle;
raffle.add("David");
raffle.add("Bjarne Stroustrup");
raffle.add("Matthew");
raffle.add("Thomas");
raffle.add("Christian");
raffle.add("Sevy");
raffle.add("Nolan");
while (1) {
std::cout << "raffle.pick(): " << raffle.pick() << std::endl;
}
return 0;
}
Multiple.cpp
#include <iostream>
class SuperA {
public:
void compute() {
std::cout << "in A" << std::endl;
}
};
class SuperB {
public:
void compute() {
std::cout << "in B" << std::endl;
}
};
class SubC : public SuperA, public SuperB {
public:
void compute() {
std::cout << "in C" << std::endl;
}
};
int main(int argc, char **argv) {
SubC c;
/* c.SuperA::compute(); */
c.compute();
return 0;
}
random.cpp
#include <cstdlib>
#include <iostream>
int main(int argc, char **argv) {
int n = 2;
int *counts = new int[n];
for (int i = 0; i < 1000; ++i) {
counts[(int) (rand() / (float) RAND_MAX * (n - 1))]++;
}
// But rand() can return RAND_MAX. Sadly, though, it's not very likely to be
// RAND_MAX, meaning we will rarely see n - 1. Our distribution will not be
// uniform.
counts[(int) (RAND_MAX / (float) RAND_MAX * (n - 1))]++;
// Multiplying by n instead is not the answer. That'll lead to a very
// infrequent index out of bounds...
counts[(int) (RAND_MAX / (float) RAND_MAX * n)]++;
for (int i = 0; i < n; ++i) {
std::cout << "counts[" << i << "]: " << counts[i] << std::endl;
}
delete[] counts;
// Instead we normalize to a value in [0, 1). When we multiply by n,
// we will never get n back out, since the random number < 1.
int *better_counts = new int[n];
for (int i = 0; i < 1000; ++i) {
better_counts[(int) (rand() / (float) (RAND_MAX + 1.0f) * n)]++;
}
for (int i = 0; i < n; ++i) {
std::cout << "better_counts[" << i << "]: " << better_counts[i] << std::endl;
}
delete[] better_counts;
return 0;
}
Haiku
Have just one parent
Calling for help is simpler
It’s not O(N)
Calling for help is simpler
It’s not O(N)