CS253: Software Development with C++

Fall 2022

Proxy Objects

Show Lecture.ProxyObjects as a slide show.

CS253 Proxy Objects

The problem

// C style
int foo[2][3];
foo[1][2] = 24;
cout << foo[1][2];
// Using object
TwoD bar(2,3);
bar[1][2] = 24;
cout << bar[1][2];

Start small

Let’s start with a one-dimensional array object, a thin wrapper around a vector:

class OneD {
    vector<int> data;
  public:
    OneD(int size) : data(size) { }
    int& operator[](int i) { return data[i]; }
};
OneD a(42);
a[10] = 33;
a[20] = 55;
cout << a[10]+a[20];
88

First naïve 2D attempt

That worked ok, so let’s add a second argument to operator[]:

class TwoD {
    const int height;
    vector<int> data;
  public:
    TwoD(int w, int h) : height(h), data(w*h) { }
    int& operator[](int x, int y) { return data[x*height + y]; }  // 🦡
};
c.cc:6: error: ‘int& main()::TwoD::operator[](int, int)’ must have exactly 
   one argument

Oops—operator[] takes only one argument.

Regroup

Second attempt

class TwoD {
    const int height;
    vector<int> data;
  public:
    TwoD(int w, int h) : height(h), data(w*h) { }
    int& operator()(int x, int y) { return data[x*height + y]; }
};
TwoD a(2,3);
a(1,2) = 24;
cout << a(1,2);
24

Analyze

New approach:

Use a proxy class

struct Proxy {
    int *const dp;
    Proxy(int *dataptr) : dp(dataptr) { }
    int& operator[](int y) { return dp[y]; }
};
class TwoD {
    const int height;
    vector<int> data;
  public:
    TwoD(int w, int h) : height(h), data(w*h) { }
    Proxy operator[](int x) { return &data[x*height]; }
};
TwoD a(2,3);
a[1][2] = 24;
cout << a[1][2];
24

Adjustment

With a nested class

class TwoD {
    struct Proxy {
        int *const dp;
        Proxy(int *dataptr) : dp(dataptr) { }
        int& operator[](int y) { return dp[y]; }
    };
    const int height;
    vector<int> data;
  public:
    TwoD(int w, int h) : height(h), data(w*h) { }
    Proxy operator[](int x) { return &data[x*height]; }
};
TwoD a(2,3);
a[1][2] = 24;
cout << a[1][2];
24