2

I'm creating a subclass vector and I would like to overload its = operator (originally, it was the + operator), but if I assign the result of it to a reference, it doesn't modify the original object.
It seems I'm missing something about C++ references, but I don't know what it is. If someone could kindly point me the error, I'd be very grateful.

Here is the code (compiled on Ubuntu 12 with g++)

#include <iostream>
#include <vector>

using namespace std;
class myvector : public vector<long double> {
    public: 
    int n_elements;
    myvector(int elems){
        n_elements = elems;
        reserve(n_elements);
    }
    myvector(int elems,long double initWith){
        n_elements = elems;
        reserve(n_elements);
        for (int i=0; i<n_elements; i++)    
            (*this)[i]=initWith;
    }
    myvector& operator= (const vector<long double>& v){
        for(int i = 0; i < n_elements; i++) 
            (*this)[i]=v[i];

        return *this;           
    }   
};

#define SIZE 200 
void fill(myvector& m){
    myvector temp = myvector(SIZE,1.0);
    cout <<"0 "<< temp[0] << endl; // (0) returns 1
    m = temp;
    cout <<"1 "<< m[0] << endl; // (1) returns 12
}
int main(){
    myvector m = myvector(SIZE,12.0);
    fill(m);
    cout <<"2 "<< m[0] << endl; // (2) returns 12
    myvector n = myvector(SIZE,1.0);
    cout <<"3 "<< n[0] << endl; // (3) returns 1
}
José M
  • 3,294
  • 1
  • 14
  • 16
  • 7
    STL containers are [not meant to be subclassed](http://stackoverflow.com/questions/1647298/why-dont-stl-containers-have-virtual-destructors), and they don't provide virtual destructors. You shouldn't do this. – user229044 Mar 21 '13 at 19:35
  • 4
    `reserve` does not resize a vector. – juanchopanza Mar 21 '13 at 19:37
  • `I'm creating a subclass vector` Why's that? – Lightness Races in Orbit Mar 21 '13 at 19:39
  • @juanchopanza: That looks like the answer. – Jesse Good Mar 21 '13 at 19:41
  • Use resize instead of reserve. And I also agree that you shouldn't be inheriting from the vector. – Rich Mar 21 '13 at 19:43
  • I use reserve() instead of resize() because I do not need the extra functionality of initializing the elements, I'll later initialize them with random values, I only need to avoid segfault. (They are very big vectors, so I'd rather allocate them on creation than have it reallocate after adding n elements) @meagar After reading the article, I agree that I should not subclass STL container, thanks! – José M Mar 21 '13 at 21:17
  • @meagar You were right, the problem is the reserve(), using resize() it works as intended. Thank you! – José M Mar 22 '13 at 10:05

1 Answers1

0

This code

myvector(int elems,long double initWith){
    n_elements = elems;
    reserve(n_elements);
    for (int i=0; i<n_elements; i++)    
        (*this)[i]=initWith;
}

should simply invoke the base class version:

myvector(int const elems, long double const initWith)
    : vector<long double>(elems, initWith)
{}

This will fix the fact that you have two measures of length, vector.size() and n_elements, that are getting out of sync. Just get rid of n_elements entirely and use the size() function you inherited.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • You are right about this. The real code (the one I posted here is a snippet highly reduced for the sake of my question) involves matrix (hence the n_rows and n_columns that got reduced to n_elements) being initialized with normal-distributed values. – José M Mar 21 '13 at 21:10
  • After a little testing, your answer corrects the issue, the problem in my solution is the reserve, that doesn't work as I thought (as the comments in the question state, I should use resize). Thank you! – José M Mar 22 '13 at 10:02