1

I am making an hierarchy of sorts and am having trouble adding an element to a vector. I simplified the code and still cannot add an element to the vector as expected. The hierarchy looks like:

Pdb > Chain > strings

Pdb and Chain are class names and strings is the name of a vector belonging to Chain. I cannot push_back to add a string to strings. You may get a better idea looking at my code:

Chain Class:

class Chain {
  string chain_id;
  vector<string> strings;

public:
  Chain(string id_) { chain_id = id_; }
  vector<string> GetStrings() { return strings; }
  void AddString(string s) { 
    cout << "Size of strings BEFORE push_back in AddString: " << strings.size() << endl;
    strings.push_back(s); 
    cout << "Size of strings AFTER push_back in AddString: " << strings.size() << endl;
  }
  string GetChainId() { return chain_id; }
};

Pdb class:

class Pdb {
  string pdb_id;
  vector<Chain> chains;

public:
  Pdb(string id_) { pdb_id = id_; }
  vector<Chain> GetChains() { return chains; }
  void AddChain(Chain c) { chains.push_back(c); }
  string GetPdbId() { return pdb_id; }
};

main:

int main () {

  vector<Pdb> pdbs;
  pdbs.push_back(Pdb("1ubq"));
  cout << "\n\t1. " << pdbs[0].GetPdbId() << endl;
  pdbs[0].AddChain(Chain("A"));
  cout << "\n\t2. " << pdbs[0].GetChains()[0].GetChainId() << endl;
  pdbs[0].GetChains()[0].AddString("Whateva");
  cout << "\n\t3. Size of strings after AddString in main: " << pdbs[0].GetChains()[0].GetStrings().size() << endl;
  return 0;
}

This outputs:

1. 1ubq

2. A
Size of strings BEFORE push_back in AddString: 0
Size of strings AFTER push_back in AddString: 1

3. Size of strings after AddString in main: 0

As you can see the AddString function is adding an element to stings within the AddString function itself but when I GetStrings back in main, after executing AddString, strings is empty. I do not understand why this is happening. Any help would be much appreciated.

John Dibling
  • 99,718
  • 31
  • 186
  • 324
NCAggie
  • 97
  • 2
  • 6

1 Answers1

4

The problem is that you return a copy of the member, not the member itself:

vector<Chain> GetChains()

should be

vector<Chain>& GetChains()

for this to work.

I must note that you're heavily breaking the single responsibility principle. You're operating on members directly, which can't be a good idea. Consider replacing:

pdbs[0].GetChains()[0].AddString("Whateva");

with something like

pdbs[0].AddStringToChain(0,"Whateva");
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • Thank you for the quick response! I am new to c++ and am not sure what the & is all about. Why can I add chains further up the hierarchy without &? I dont know about your second point, I don't think it will work in the real context. In the real code the vector'strings' is actually a vector of user-defined Residue objects. As such the chains and residues should be their own entity. If I do your second suggestion the code will get messy fast, especially in accessing residues. – NCAggie Jun 28 '12 at 15:02