CS 330 Lecture 24 – Generics/templates
April 2, 2012 by Chris Johnson. Filed under cs330, lectures, spring 2012.
Agenda
- named constructor pattern
- typing: strong and static and dynamic
- a peril of static typing: code
- Java generics
- C++ templates
TODO
Code
makefile
drawer: drawer.cpp Vector.h Matrix.h Matrix.cpp Vector.cpp
g++ -Wall -o drawer Vector.cpp Matrix.cpp drawer.cpp
Vector.cpp
#include <cassert>
#include "Vector.h"
Vector2::Vector2() :
x(0.0f),
y(0.0f) {
}
Vector2::Vector2(float x, float y) :
x(x),
y(y) {
}
float& Vector2::operator[](int index) {
assert(index >= 0 && index <= 1);
return index == 0 ? x : y;
}
const float& Vector2::operator[](int index) const {
assert(index >= 0 && index <= 1);
return index == 0 ? x : y;
}
Vector2 Vector2::operator+(const Vector2& other) {
return Vector2(x + other.x, y + other.y);
}
std::ostream& operator<<(std::ostream& out,
const Vector2& v) {
out << v[0] << "," << v[1];
return out;
}
Vector.h
#ifndef VECTOR_H
#define VECTOR_H
#include <iostream>
#include <fstream>
class Vector2 {
public:
Vector2();
Vector2(float x, float y);
// write a subscript operator
float& operator[](int index);
const float& operator[](int index) const;
Vector2 operator+(const Vector2& other);
// overload a print operator
private:
float x;
float y;
};
std::ostream& operator<<(std::ostream& out,
const Vector2& v);
#endif
Matrix.cpp
#include <cmath>
#include "Matrix.h"
Matrix2::Matrix2() {
}
float& Matrix2::operator()(int r, int c) {
return elements[r * 3 + c];
}
const float& Matrix2::operator()(int r, int c) const {
return elements[r * 3 + c];
}
Vector2 operator*(const Matrix2& m, const Vector2& v) {
Vector2 product;
// dot m's row 0 with v's col 0
product[0] = m(0, 0) * v[0] + m(0, 1) * v[1] + m(0, 2);
// dot m's row 1 with v's col 0
product[1] = m(1, 0) * v[0] + m(1, 1) * v[1] + m(1, 2);
return product;
}
Matrix2 Matrix2::GetScale(float x, float y) {
Matrix2 m;
m(0, 0) = x;
m(1, 1) = y;
m(2, 2) = 1.0f;
m(0, 1) = m(0, 2) = m(1, 0) = m(1, 2) = m(2, 0) = m(2, 1) = 0.0f;
return m;
}
Matrix2 Matrix2::GetRotate(float degrees) {
float radians = degrees * 3.14159f / 180.0f;
Matrix2 m;
m(0, 0) = cos(radians);
m(0, 1) = -sin(radians);
m(1, 1) = cos(radians);
m(1, 0) = sin(radians);
m(2, 2) = 1.0f;
m(0, 2) = m(1, 2) = m(2, 0) = m(2, 1) = 0.0f;
return m;
}
/* ------------------------------------------------------------------------- */
Matrix.h
#ifndef MATRIX_H
#define MATRIX_H
#include "Vector.h"
class Matrix2 {
public:
Matrix2();
float& operator()(int r, int c);
const float& operator()(int r, int c) const;
static Matrix2 GetScale(float x, float y);
static Matrix2 GetRotate(float degrees);
static Matrix2 GetTranslate(float x, float y);
private:
/* float elements[9]; */
double elements[9];
};
Vector2 operator*(const Matrix2& m, const Vector2& v);
#endif
drawer.cpp
#include <cmath>
#include <iostream>
#include "Matrix.h"
#include "Vector.h"
int main() {
Matrix2 rotate = Matrix2::GetRotate(30.0f);
Matrix2 scale = Matrix2::GetScale(1.04f, 1.04f);
/* float radians = 30.0f * 3.14159f / 180.0f; */
/* transform(0, 0) = cos(radians); */
/* transform(0, 1) = -sin(radians); */
/* transform(1, 0) = sin(radians); */
/* transform(1, 1) = cos(radians); */
/* transform(0, 2) = 0.0f; */
/* transform(1, 2) = 0.0f; */
/* transform(2, 0) = 0.0f; */
/* transform(2, 1) = 0.0f; */
/* transform(2, 2) = 1.0f; */
Vector2 point(1.0f, 0.0f);
std::cout << point << std::endl;
for (int i = 0; i < 120; ++i) {
point = rotate * point;
point = scale * point;
std::cout << point << std::endl;
}
/* Vector2 point2(1.0f, 2.0f); */
/* Vector2 sum = point + point2; */
/* Vector2 sum = point.operator+(point2); */
/* std::cout << "sum[0]: " << sum[0] << std::endl; */
/* std::cout << "sum[1]: " << sum[1] << std::endl; */
/* std::cout << "sum: " << sum << std::endl; */
/* std::cout << "point[0]: " << point[0] << std::endl; */
/* std::cout << "point[1]: " << point[1] << std::endl; */
/* point[0] = 11.0f; */
/* std::cout << "point[0]: " << point[0] << std::endl; */
/* std::cout << "point[1]: " << point[1] << std::endl; */
/* point[0] // point.getX() */
/* point[1] // point.getY() */
}
ArrayList.java
package cs330;
public class ArrayList {
private Object[] stuff;
private int size;
public ArrayList() {
stuff = new Object[10];
size = 0;
}
public Object get(int i) {
return stuff[i];
}
public int size() {
return size;
}
public boolean add(Object o) {
if (size == stuff.length) {
Object[] aWholeLotMoreStuff = new Object[stuff.length * 2];
System.arraycopy(stuff, 0, aWholeLotMoreStuff, 0, stuff.length);
stuff = aWholeLotMoreStuff;
}
stuff[size] = o;
++size;
return true;
}
}
Haiku
on code reuse:
“Don’t reinvent the wheel!”
Ignore them. We don’t need wheels.
We need inventors.
show