-2

I am trying to create list of existing objects in vector. Here is what I have so far:

   void Program::addClient(string name){
      vector<Client> *ptr = &(impl->clients);
      Client cl(name);
      ptr->push_back(cl);
   }

The problem is that destructor is going to be called two times: first, when method addClient ends and second time, when destructor of this methods class will be called. Because of that, I get an error (obviously). So I thought of writing something like this:

   void Program::addCategory(string name){
      vector<Category> *ptr = &(impl->categories);
      Category *c = new Category(name);
      ptr->push_back(c);
   }

By doing so, I believe, I would get rid of destructor problem, but there is another problem. My IDE throws an error at sign -> between ptr and push_back, saying "no instance of overload function".

What I should do and maybe you have any tips?

  • 2
    If `Client` is correctly copyable and/or movable, then creating and destroying the temporary won't cause an error. If it's not, then it should be. – Mike Seymour Nov 12 '13 at 17:13
  • What does the declaration of `Client` look like? – Zac Howland Nov 12 '13 at 17:15
  • I can show you full code of Client.cpp here: http://pastebin.com/Hnfg0vKY Maybe I should try to reload the copying constructor? I am not sure, really, what I should do... –  Nov 12 '13 at 17:17
  • You should use `std::shared_ptr` for your `i` pointer – Erbureth Nov 12 '13 at 17:20
  • @Erbureth thank you for the tip, but since I am a student at university, I have to program by strict rules (we had an example about this)... I will keep in mind about this, though. Thanks :) –  Nov 12 '13 at 17:22
  • In that case you have to implement reference counting by yourself and call `delete i;` only when the counter reaches zero. – Erbureth Nov 12 '13 at 17:24
  • 1
    @Fractal: If you're not allowed to use smart pointers then read up on the [Rule of Three](http://stackoverflow.com/questions/4172722) and give your class a copy constructor and copy-assignment operator. – Mike Seymour Nov 12 '13 at 17:32

2 Answers2

1

How to add objects to vectors correctly, without calling destructor two times

With emplace_back:

ptr->emplace_back(name);

The problem is that destructor is going to be called two times ... Because of that, I get an error (obviously).

This should not cause an error for a well behaved class. If calling push_back is causing you problems, that hints at something wrong with the Client class. Make sure it is correctly copyable and assignable.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • 2
    If the original code doesn't work for the OP, then she has bigger problems, though... – Kerrek SB Nov 12 '13 at 17:13
  • @KerrekSB I was going by the title of the question. I couldn't make much sense out of the question itself so I stopped reading. – juanchopanza Nov 12 '13 at 17:14
  • @juanchopanza - If you are not able to understand question and you are posting answer to a question, which you don't understand, then you are just a spammer, who should be thrown out from this community... –  Nov 12 '13 at 17:16
  • @Fractal As I said, I am answering the title of the question, and I am far from being a spammer. – juanchopanza Nov 12 '13 at 17:17
  • The problem with the `push_back` is in the second example, not the first. And it is that he has a vector of `Category` objects, but is trying to push back a pointer to a `Category` object. – Benjamin Lindley Nov 12 '13 at 17:19
  • Oh, you're right. I thought the only problem with the first example was undesired destructor calls. I didn't notice the *"Because of that, I get an error (obviously)."* -- Which is a funny statement, because it's not at all obvious that there should be an error because of that. There obviously should *not* be an error there, unless the class is broken. – Benjamin Lindley Nov 12 '13 at 17:25
0

The issue is your misconception

The problem is that destructor is going to be called two times: first, when method addClient ends and second time, when destructor of this methods class will be called.

The above is NOT a problem. When you insert an object into a std::vector<Client>, you are inserting a copy. The destructor gets run twice because after the copy is made, there are two objects.

If this is in fact causing you an error, it is fairly likely that Client is not properly copyable, and you need to either make it copyable or reconsider how you're using it.

Dave S
  • 20,507
  • 3
  • 48
  • 68