0

In my homework, I need to copy a map so if I change something in mapB the same change should happen to mapA, but can't figure out how to.

I searched around, and the closest thing I found was this: Shallow copy of a Map in Java but sadly this is in java and not in C++.

I thought something like this, but it doesn't work. Why, and what would be the right code?

class Mymap
{
private:
    std::map <int, int> *PM;
public:

    Mymap(std::map <int, int>* x)
    {
        PM = new std::map<int,int>(x);
    }
};

int main()
{
    std::map<int, int> mapA;
    Mymap mapB(mapA);
    return 0;
}
Dodande
  • 69
  • 4
  • 1
    You just need `Mymap(std::map &x) : PM{&x} { }`. – Quentin Jul 02 '19 at 16:00
  • 2
    [The Definitive C++ Book Guide and List](https://stackoverflow.com/q/388242/5910058). – Jesper Juhl Jul 02 '19 at 16:01
  • The point being that `PM = new std::map(*x);` takes a deep copy of the map. (The code you wrote won't even compile). – Martin Bonner supports Monica Jul 02 '19 at 16:01
  • Maybe you need a map of pointers? Then copies of such map will contain values which will point to the same objects. – marcinj Jul 02 '19 at 16:06
  • `but it doesn't work.` This is not a useful problem description. How does it not work? What did you expect? – eerorika Jul 02 '19 at 16:07
  • Shallow copying *anything* means copying just the top level data members, without chasing pointers or references. (If your homework literally tells you to do that, then it is my personal opinion is that your course could be of negative value). You cannot shallow copy an std::map. It isn't quite clear what exactly you are trying to shallow copy. – n. 'pronouns' m. Jul 02 '19 at 17:00
  • Useful reading: [Why should C++ programmers minimize use of 'new'?](https://stackoverflow.com/questions/6500313/why-should-c-programmers-minimize-use-of-new) – user4581301 Jul 02 '19 at 17:03
  • Expanding on that, a huge point of the library containers is to perform memory management and take care of the [Rules of Three and Five](https://en.cppreference.com/w/cpp/language/rule_of_three) for you so you can focus on describing your program's behaviour, not the container's. Dynamically allocating a library container ruins that great work on your behalf and makes your job much, much more difficult. – user4581301 Jul 02 '19 at 17:08
  • 1
    Do you want changes to the _map_ to be reflected, or changes to the elements of the map? Subtly different things! (e.g. what happens when you add a new element?) – Lightness Races in Orbit Jul 02 '19 at 17:10

2 Answers2

2

To be honest, I have the feeling the actual problem is that you do not fully understand the difference between a shallow copy and deep copy in c++.

In very simple terms: shallow copy = copy the pointer, deep copy = copy what the pointer points to.

Your code is a variation of deep copy by taking what the pointer points to and create a new instance from that (assuming it would compile).

I will give you a simple example and leave the rest to you:

#include <iostream>

struct foo {
    int * some_pointer;
    void deep_copy( const foo& other) {
        // copy the value
        *some_pointer = *(other.some_pointer);
    }
    void shallow_copy( const foo& other) {
        // make some_pointer point to the same as other.some_pointer
        some_pointer = other.some_pointer;
    }
 };

 int main() {
     int x = 0;
     int y = 42;
     foo f{&x};
     foo g{&y};
     f.deep_copy(g);
     y = 3;
     std::cout << *f.some_pointer << "\n";
     std::cout << *g.some_pointer << "\n";
     f.shallow_copy(g);
     y = 5;
     std::cout << *f.some_pointer << "\n";
     std::cout << *g.some_pointer << "\n";
 }

This prints:

42
3
5
5

Because first f.deep_copy(g); copies the value and afterwards changing the value of y (which initially was bound to g) has no effect on f.

On the other hand, after f.shallow_copy(g); both f.some_pointer and g.some_pointer both point to y, hence modifiying y is reflected on both, f and g.

463035818_is_not_a_number
  • 64,173
  • 8
  • 58
  • 126
1

In my homework, I need to copy a map so if I change something in mapB the same change should happen to mapA, but can't figure out how to.

I understand you want to have two maps with the same values, and if you modify object (value) in one map then this modification will be reflected in second map. Below code presents how to do this:

using map_type = std::map<int, std::shared_ptr<std::string>>;

map_type m1;
// Here store some value in m1
m1[1] = std::make_shared<std::string>("one");

// Make a copy, std::string objects are not copied, only pointers are being copied
map_type m2 = m1;

// Now modify m1 map
*m1[1] = "its one";

// And m2 will contain the above m1 modification
std::cout << *m2[1];

https://coliru.stacked-crooked.com/a/d37a246ff0d1bb59

Of course, if you add new elements to map one, then they will not be seen in map two.

marcinj
  • 44,446
  • 9
  • 70
  • 91