-1

I have several problems with a code which has a similar structure to this one shown. It doesn't work! I think the main problem is the push_back function, that I need for other scopes (I need to build a vector of classes during the operations, and also have pointers internally the single class). Anyone knows how to solve it? Thanks

#include <vector>
using namespace std;

class meow {
public:
  int b;
  meow() {
    b = 1;
  } 
  meow(int a) {
    b = a;
  } 
};

class dog {
public:
  vector<meow> H;
  vector<vector<meow>::iterator> HP;

  dog()
    : HP(2), H(2) {
   HP[0] = H.begin();
   HP[1] = H.begin() + 1;
  }
};

int main() {
  vector<dog> WOOF(1);
  WOOF.push_back(dog());
  meow ok(2);
  (*WOOF[1].HP[0]) = ok;
  cout << (*WOOF[0].HP[0]).b << endl;
  cout << (*WOOF[1].HP[1]).b << endl;
}

OK, I understood the deal, so is it possible to do something like this, in the event that I won't use push_back after in the code?

#include "stdafx.h"
#include <iostream>
#include <vector>

using namespace std;

class meow {
public:
  int b;
  meow() {
    b = 1;
  } 
  meow(int a) {
    b = a;
  } 
};

class dog{
public:
vector <meow> H;
vector<vector<meow>::iterator> HP;
dog():
    HP(2),H(2){
}
    void Referring(){
        HP[0]=H.begin();
        HP[1]=H.begin()+1;  
    }
};


int main() {
  vector<dog> WOOF(1);
  WOOF.push_back(dog());
  for(int i=0;i<WOOF.size();++i){
      WOOF[i].Referring();

  }
  meow ok(2);
  (*WOOF[1].HP[0]) = ok;
  cout << (*WOOF[0].HP[0]).b << endl;
  cout << (*WOOF[1].HP[1]).b << endl;
}
The Newbie Toad
  • 186
  • 2
  • 15
  • 1
    What "doesn't work"? What do you expect to happen, and what happens instead? Do you get any error messages? You don't really make it clear what is going wrong... – sth Mar 02 '14 at 14:02
  • 1
    Classical issue in a case like this is that a push_back will move the entire vector in memory and any pointers to it will become dangling. – user2672165 Mar 02 '14 at 14:03

2 Answers2

3

In dog::HP you store iterators pointing to elements of the dog::H vector. When a dog object is copied, the copied iterators in HP of the new object will still point to the vector H of the original object. When the original object is destroyed, the iterators in the new object won't point to anything useful anymore.

This is what happens in main(), where a temporary dog object is copied into WOOF.

Also generally it's probably not a good idea to store iterators the iterators like this in the first place.. When H gets modified, all the iterators in HP will be invalidated and are no longer safe to use.

sth
  • 222,467
  • 53
  • 283
  • 367
0

The dog class needs a copy ctor. That is at least one fatal issue which leads to disaster at push_back as copy of dog then is created. The default copy ctor will copy the pointers by value so they will point to the wrong (old) address. Enhanced dog class:

class dog {
public:
  vector<meow> H;
  vector<vector<meow>::iterator> HP;

  dog() : HP(2), H(2)
  {
     HP[0] = H.begin();
     HP[1] = H.begin() + 1;
  }
  dog(const dog& rhs) : H(rhs.H),HP(2)
  {
     HP[0] = H.begin();
     HP[1] = H.begin() + 1;
  }
  dog& operator=(const dog& rhs)
  {
     if(&rhs==this)
        return *this;
     H=rhs.H;
     HP[0] = H.begin();
     HP[1] = H.begin() + 1;
  }

};

user2672165
  • 2,986
  • 19
  • 27
  • @Tommaso Ferrari: In my answer above is a proposed solution! Create a copy constructor (and a copy assignment operator). See http://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming). A destructor is not needed in your case, but there are examples. – user2672165 Mar 02 '14 at 17:19
  • I've done as u sugested. It doesn't work! In debug says that there's a problem at line `HP[0] = H.begin();` – The Newbie Toad Mar 02 '14 at 18:25
  • @Tommaso Ferrari: One line was wrong. Change to: dog(const dog& rhs) : H(rhs.H),HP(2). HP size wasn't initialized to two. – user2672165 Mar 02 '14 at 18:36