0

I am currently creating a class that has to be derived from std:: vector. I realize its probably bad to do this but I'm required to. Now my question is how do you access the created vector in the member functions to basically make the class access itself like a regular vector of integers? For example I am looking for the equivalent of myVector.at(0) to return the first term in the vector. Also, the size of the vector should always be 6. Here is the code I have so far:

class aHistogram : public vector<int>
{
public:
    aHistogram(); //default constructor for histogram class
    void update(int face); //Function to update histogram
    void display(int maxLengthOfLine); //Displays histogram to the scale of maxLengthOfLine using    x's
    void clear();//Function to clear histogram bin counts
    int count(int face) const; // Function to return number of times a face has appeared
private:
    int numx, m, j; //Variables used in functions
};

#endif

The function that requires the class to access itself is below, I know there is no vector called "myVector" but what I'm lost about is the equivalent syntax to be able to perform the operation.

void aHistogram::clear() 
{
    //Clears bin counts to 0
    myVector.at(0) = 0;
    myVector.at(1) = 0; 
    myVector.at(2) = 0;
    myVector.at(3) = 0;
    myVector.at(4) = 0;
    myVector.at(5) = 0;
}
KoolaidLips
  • 247
  • 1
  • 8
  • 20
  • @πάνταῥεῖ That is not a duplicate of this question. That question addresses pros/cons of inheriting from standard library types, and what types are designed to be inherited from. The OP here is asking a simple syntax question. – Praetorian Dec 05 '14 at 15:43
  • Use `vector`'s member functions as if they're defined by your class. You only need to qualify the calls explicitly if your class defines a member function that already exists in the `vector` interface, such as `clear()`. In that case, you can use `vector::clear();`. For example: http://coliru.stacked-crooked.com/a/d3cec10a471438eb – Praetorian Dec 05 '14 at 15:48
  • @Praetorian Thanks so much! Worked exactly how I needed. – KoolaidLips Dec 05 '14 at 15:54
  • Glad it helped. But please do read the answers below, and consider using composition instead of inheritance, unless you're being forced to use inheritance for a class or some such. Even in that case you should consider `private` inheritance rather than `public`. – Praetorian Dec 05 '14 at 15:58
  • I'm interested to know why you feel you are required to do this even if you know it is a bad idea. Is it a 'technical constraints' required to or a 'my boss says do it this way' required to? – sjdowling Dec 05 '14 at 16:25
  • My teacher wants it done specifically this way, have no idea why – KoolaidLips Dec 06 '14 at 16:45

3 Answers3

2

If the function in question isn't overridden in the derived class, you can just call it:

void HistoGram::clear()
{
    at( 0 ) = 0;
    //  ...
}

This is also true for operators, but you'll have to use (*this) as the left hand operator:

void HistoGram::clear()
{
    (*this)[0] = 0;
    //  ...
}

If the function or operator is overridden, you'll either have to qualify the function name,

void HistoGram::clear()
{
    std::vector<int>::at( 0 ) = 0;
    //  ...
}

or cast the this pointer to the base class type:

void HistoGram::clear()
{
    (*static_cast<std::vector<int>*>( this ))[0] = 0;
    //  ...
}

But are you sure that you want public inheritance here? You state that the size of the vector should always be 6. There's no way you can guarantee that using public inheritance; at the least, you need private inheritance, and then using declarations for the operations that you want to support. (I've a couple of cases where I've needed restricted std::vector like this, which I've implemented using private inheritance. And sometimes forwarding functions, when for example I've wanted to expose only the const version of the function.)

Also: there are very, very few cases where std::vector<>::at is appropriate. Are you sure you don't want [], with the bounds checking you get in most modern implementations.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
0

Instead of deriving from std::vector, in this case contain one (as a data member).

The problem with deriving is that it's then possible to treat a Histogram instance as just a std::vector, doing things that invalidate assumptions about the values of added data members.

In more technical jargon, with class derivation you have no guaranteed class invariant above the one provided by std::vector.

As a general rule of thumb, think of data member before class inheritance.

Sometimes inheritance is the thing, even inheritance from standard library container classes (e.g., std::stack is designed for inheritance), but not in this case.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
0

About this: the size of the vector should always be 6.

You probably want to forbid some functionality to the user of the class. For example

  • vector::push_back
  • vector::pop_back
  • vector::insert

are functionalities that can change the size of the vector.

You can achive this by making such functions private members in the child class:

class aHistogram : public vector<int>
{
public:
    aHistogram(){};

private:

    vector<int>::push_back;
    vector<int>::pop_back;
    vector<int>::insert;

    int numx, m, j;
};
Raydel Miranda
  • 13,825
  • 3
  • 38
  • 60
  • Making certain functions private isn't future proof though, what if more mutable functions are added in a future standard or implementation? Safer to inherit privately and make what is allowed explicit. – sjdowling Dec 05 '14 at 16:22
  • If an `aHistogram` is bound to a reference to `vector` then all the functionality of `vector` is directly available. I.e. this is not a good solution. Generally a derived class can meaningfully open up access to things but it can't meaningfully restrict access. – Cheers and hth. - Alf Dec 05 '14 at 23:21