0

Assume I have a class:

class A {
  public:
    int key;
    map<int,int> a;
};

Obj_A1 is an existing object of class A. Somewhere in my problem, I want to construct another object called Obj_A2 and update the members of Obj_A2 like this:

Obj_A2.key = Obj_A1.key + 1;
Obj_A2.a = Obj_A1.a;         // When a is large, this copy operation will be really time consuming.

So I try to get around the real data transfer, considering that maybe I can assign the address of Obj_A2.a with the address of Obj_A1.a. In case, Obj_A2.a is just Obj_A1.a in the memory, and there is not data duplication at all.

So I did something silly (I am new to C++), which is, &Obj_A2.a = &Obj_A1.a, and had some compiler error.

Does anyone know the right way to do this?

Thanks a lot.

2 Answers2

2

It sounds like you want a shared pointer.

#include <memory>
#include <map>

class A {
  public:
    int key;
    std::shared_ptr<std::map<int,int>> a;
};

int main() {
    A Obj_A1, Obj_A2;
    Obj_A1.key = 0;
    Obj_A1.a = std::make_shared<std::map<int,int>>();

    Obj_A2.key = Obj_A1.key + 1;
    Obj_A2.a = Obj_A1.a;

    // or, more simply
    // Obj_A2 = Obj_A1;
    // Obj_A2.key++;
}

With this, Obj_A2.a will point to the same map as Obj_A1.a, and modifications to the map from one will be seen by the other.

Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274
  • @JimGreen: when `a` is a pointer (shared or otherwise), you'll need to use `a->begin()` instead of `a.begin()` etc.. – Tony Delroy Jun 29 '15 at 02:05
  • Thank you, sir! Sorry about my mistake :P Now my problem is a compiler error like this: error: no match for 'operator=' (operand types are 'std::map, int>' and 'std::shared_ptr, int> >') The corrresponding commend causing this error is: Obj_A.a = make_shared,int>>(); Do you know how to fix this? –  Jun 29 '15 at 02:29
  • @JimGreen: It sounds like you didn't make `A::a` a shared pointer. – Benjamin Lindley Jun 29 '15 at 06:32
  • Thank you for being patient with a beginner like me :) May I have one more question. Class A is used by many other things in a much bigger program, so I was not suggested to change "a" from a map to a pointer. If I do that, other people using the same class will be unhappy. Do you think it is possible to make "a" has the same address with an existing variable (so unlike an explicit "Copy operation" the data is not duplicated) without changing the class A? By "without changing the class A", I mean I am only allowed to add codes in the main function. –  Jun 29 '15 at 18:15
  • @JimGreen: So you say you can't change the class `A`. Can you change the type of the "existing variable". (i.e. the one mentioned in *"Do you think it is possible to make "a" has the same address with an existing variable"*). Or is that just another `a` member of a different `A` object? – Benjamin Lindley Jun 29 '15 at 18:18
  • Thank you for your reply, sir! It is just another a member of a different A object. In my original code, the most time-consuming operation is: Obj2.a = Obj1.a; It is just transferring the entire "a" of Obj1 to the "a" of Obj2 without any changes. So I planned to focus on "Obj2.a = Obj1.a;" and I was wondering if I could just make the variable "a" of Object2 have the same address with "a" of Object1, so I just reuse the existing data without real data duplication or data transfer in the memory. –  Jun 29 '15 at 18:32
  • @JimGreen: After the transfer, do you need to still be able to access the map from the variable `Obj1.a`? If not, then you can do `Obj2.a = std::move(Obj1.a);`. This will give `Obj2.a` ownership of the internal map data structure (which is dynamically allocated behind the scenes). But it will leave `Obj1.a` in a valid, but unspecified state (probably empty). Otherwise, if you need `Obj1.a` to also hold the same data it did before, then you are out of luck. You cannot make two objects have the same address. – Benjamin Lindley Jun 29 '15 at 18:44
  • Thank you, sir! Yes, I do not need Obj1.a anymore. So I tried std::move() function, and I can see a small improvement of run-time. I guess since it is dynamically allocated behind the scenes, the runtime overhead due to data copy and paste in the memory still exists, right? –  Jun 29 '15 at 19:03
  • @ Benjamin Lindley: If we really want to have significant speedup, do you suggest that we get back to shared_ptr and modify Class A? –  Jun 29 '15 at 19:08
  • @JimGreen: When you use `std::move`, the dynamically allocated data is not copied at all. The only thing copied is a few pointers and integers that are used for keeping track of the data. And no, using a `shared_ptr` will not result in a speedup over using `std::move`. If I knew you didn't need `Obj1.a` anymore, I would have suggested using `std::move` in the first place, rather than a shared pointer. – Benjamin Lindley Jun 29 '15 at 19:10
  • @JimGreen: For more information on `std::move`, read this: http://stackoverflow.com/questions/3106110/what-are-move-semantics – Benjamin Lindley Jun 29 '15 at 19:20
  • @Benjamin Lindley: Sir, one more question. Is there a similar function with "move()" before c++11? My current situation is that my code will be eventually added to a bigger system, but the compiler for the entire system does not use c++11. –  Jul 08 '15 at 21:04
  • @JimGreen: You can swap: `std::swap(Obj2.a, Obj1.a);` – Benjamin Lindley Jul 08 '15 at 22:43
  • @Benjamin Lindley: Thank you very much : ) –  Jul 09 '15 at 00:19
0
class A {
  public:
    int key;
    map<int,int> *a;
};

...
Obj_A1.a = new map<int,int>;
...

Obj_A2.key = Obj_A1.key + 1;
Obj_A2.a = Obj_A1.a;    
Beta
  • 96,650
  • 16
  • 149
  • 150
  • Thank you for your reply. Because this operation is in some kind of member functions inside a loop, the code will keep allocating new memory space dynamically for many many times. I tried your method and my program stopped somewhere before it was finally killed by the system. Is it due to memory leak? –  Jun 29 '15 at 01:59
  • @JimGreen: It's impossible to know without seeing more of your code. – Beta Jun 29 '15 at 02:18