vendredi 7 octobre 2016

Writing an accessor method for inherited class with sparse member data?

Say I have a simple vector class, vec:

#include <iostream>
#include <stdlib.h>

class vec {
public:
    // Constructor.
    vec(int n) {
        len = n;
        data = new double[len];
    }

    // Destructor.
    ~vec() { delete [] data; }

    // Accessor.
    double & operator[](int i) const {
        check_index(i);
        return data[i];
    }

    // Other methods...
    // ....

protected:
    int len;
    double * data;
    void check_index(int i) const {
        if(i < 0 || i >= len) {
            std::cerr << "Bad access.\n";
            exit(1);
        }
    }
};

Now suppose I have a special type of vector with sparse structure, e.g., where every even-index is zero. Call this oddvec. Instances of oddvec should be declared just as with the vec class, but underneath, the memory use should be efficient since only half the data is non-zero.

The accessor for the oddvec class should return 0 if the index is even, and return the odd-index element (stored sequentially) otherwise. There a couple problems with this:

  1. The double & return type is violated if the index is even, since the constant value, 0, is returned.
  2. It's not clear to me how to handle the situation when an even index element is used as an lvalue. E.g., v[0] = 3.0 should not be allowed in the oddvec class, but is perfectly acceptable in the vector class. We can't simply throw an error when even indexes are used, because even indexes are fine as long as the intention is as an rvalue.

How do I design the accessor function for the oddvec class, while both keeping the memory storage efficient and inheriting all the methods from the parent?

Non-working example of oddvec:

class oddvec : public vec {
public:
    // Constructor.
    oddvec(int n) {
        len = n;
        data = new double[len/2];
    }

    // Accessor (doesn't work!)
    double & operator[](int i) const {
        check_index(i);

        if (i%2 == 0)
            return 0;
        else
            return data[(i-1)/2];
    }
};

Aucun commentaire:

Enregistrer un commentaire