Need to change the value of one of two vector pointers that point to the same object, but keep the same object?

This is somewhat tricky...I have an object, an "Iron Sword" in this case. It belongs to a long index of pre-created objects that the user can buy from at a shop. But, I distinguish each object through an ID, supposedly to "distinguish" the items in case the user decides to buy multiple ones.

However, it seems I failed just that. I made a vector array of pointers to the same class of said objects, and when the user buys two "Iron Swords", they will always have the same ID because they point to the same object. I tried modifying them to no avail, obviously.

How would I go about accomplishing what I wish to do?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Weapon()
{
  string itemName;
  int itemID;
  //etc etc

  void setItemID(int id)
  { itemID=id; }
}

int main()
{
  
  vector<Weapon*> inventory;
  
  //user buys 2 Iron Swords

  //Doesn't do anything!...because they are merely pointers
  inventory.at(0)->setItemID(2);
  inventory.at(1)->setItemID(5);

  //Keeps printing same number
  cout<<inventory.at(0)->getItemID();
  cout<<inventory.at(1)->getItemID();

}


Edit: Oh and I am using polymorphism in my particular program, which is why I used vector arrays
Last edited on
I would say that your problem -- and solution -- is within line 16. What do you do there?
There, I equal both vector pointers to the object that is an Iron Sword. I could declare it manually, set each object for each pointer, but there are a lot of items so I stuffed them all in a large vector array, something like this:

vector<Item*> itemIndex;

This vector pointer, I send to a function where I new all of the different items.

When a player buys an item, it sets one of his inventory pointers to the particular item. Therefore, I end up with two pointers that point to the same object, but I need to assign different ID values.

Suppose I did this, which I did actually in my program:
 
itemIndex.push_back(new Weapon("Iron Sword" //all the other different stats/etc); 


And suppose that object is in element 0, then the user buys two Iron Swords:

1
2
3
4
inventory.push_back(itemIndex[0]);
itemCount++;
inventory.push_back(itemIndex[0]);
itemCount++;
Last edited on
I feel as though the solution is very simple but I've been up all night, I can't grasp it.
here's maybe one way:
specialise again.
have an IronSword type that inherits from Weapon. Keep your id variable, but also have a static member in that class that maintains the current id number. when you instantiate a new IronSword, up this number and assign it to the new object.

but i'm not really understanding what your problem is. Surely you could use your itemName string to distinguish between different iron swords? ("Iron Sword1","Iron Sword2" etc..)?
How would I do that though? The name is declared once in the function where I create all of the items. Not sure how I would go about naming it differently for every time the user buys one.

The problem is that two bag slots point to the same object, and so any change on one item results in changes to other other bag slot, since they point to the same object.

Question, would it be possible to create a new every time the user buys an object? But, I would need to somehow initialize it, because as I said, it is polymorphic, so it could be either:
1
2
3
itemIndex(new Weapon(//etc etc);
itemIndex(new Armor(//etc etc);
itemIndex(new Potion(//etc etc); 


Since they all belong to the base class that is Item
Last edited on
Clone. Virtual function.
1
2
3
4
Item * sword = itemIndex.at(7);
Item * sword2 = sword->clone(); // returns new copy with new ID
itemIndex.push_back( sword2 );
inventory.push_back( sword2 );
Is that a pre-defined function or is there any more to it?
Also, how would it fit into my program? I will include an actual example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

vector<Item*> index;
vector<Item*> inventory;

index.push_back(new Weapon("Mithril Sword","Weapon",550,rand(),8,
							   15,18,"1H Sword",11,12,4,4,4,
							   15,10));

index.push_back(new Weapon("Witch Blade","Weapon",600,rand(),8,
							   8,12,"1H Sword",3,3,12,12,5,
							   2,15));

//Player goes to some shop

//Player buys two Mithril Swords

inventory.push_back(index[0]);
inventory.push_back(index[0]);


It is still quite blurry to me

Edit:

So, it would work if I declared an item pointer every time I buy an object, such as in this example?
1
2
3
4
5
6
//Player buys sword

Item *boughtItem=index.at(0);
Item *boughtClone=boughtItem->clone();

inventory.push_back(boughtClone);


I'm just not sure what to make of line 3 in your code, since that would mess with the original list of the items, which I want to keep static.

Last edited on
The problem is that two bag slots point to the same object

So why have you implemented like this??


I'd have some kind of factory method (or ItemFactory class), that news up the required item depending on user choice.
Last edited on
Is that a pre-defined function or is there any more to it?

No. Clone could be something like:
1
2
3
4
virtual Weapon * Weapon::clone() const
{
  return new Weapon( *this );
}


However, the fundamental problem is that if you have a static itemIndex with exactly one vorpal blade in it and player's inventory merely points to the itemIndex, then there is exactly one vorpal blade in the world, even if you pay ten times for it.

The inventory could contain pair<Item *, size_t>, (i.e. type, count) but then there are no "real" sword objects.

Therefore, you probably want to make real copies. The itemIndex will be like a menu in restaurant, and when a client orders a meal, a "real" copy of beef is generated (by cloning, factory method, etc).
Topic archived. No new replies allowed.