【问题标题】:C++ How to make a shallow copy constructor for a mapC ++如何为地图制作浅拷贝构造函数
【发布时间】:2019-11-13 07:46:06
【问题描述】:

在我的作业中,我需要复制一张地图,所以如果我在 mapB 中更改某些内容,mapA 也会发生相同的更改,但不知道如何去做。

我四处搜寻,发现最接近的是:Shallow copy of a Map in Java 但遗憾的是这是在 java 中,而不是在 C++ 中。

我想过这样的事情,但它不起作用。为什么,什么是正确的代码?

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;
}

【问题讨论】:

  • 你只需要Mymap(std::map &lt;int, int&gt; &amp;x) : PM{&amp;x} { }
  • 重点是PM = new std::map&lt;int,int&gt;(*x); 获取了地图的深层副本。 (你写的代码甚至不会编译)。
  • 也许你需要一个指针映射?然后此类地图的副本将包含指向相同对象的值。
  • 您想要反映对 map 的更改,还是对地图元素的更改?微妙不同的东西! (例如,当你添加一个新元素时会发生什么?)

标签: c++ dictionary pointers reference shallow-copy


【解决方案1】:

说实话,我感觉实际的问题是你没有完全理解 c++ 中浅拷贝和深拷贝之间的区别。

简单来说:浅拷贝 = 拷贝指针,深拷贝 = 拷贝指针指向的内容。

您的代码是深拷贝的一种变体,通过获取指针指向的内容并从中创建一个新实例(假设它可以编译)。

我给你一个简单的例子,剩下的交给你:

#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";
 }

打印出来:

42
3
5
5

因为首先f.deep_copy(g); 复制值,然后更改y 的值(最初绑定到g)对f 没有影响。

另一方面,在f.shallow_copy(g); 之后f.some_pointerg.some_pointer 都指向y,因此修改y 会同时反映在fg 上。

【讨论】:

    【解决方案2】:

    在我的作业中,我需要复制一张地图,所以如果我在 mapB 中更改某些内容,mapA 也会发生相同的更改,但不知道如何去做。

    我了解您希望拥有两个具有相同值的映射,如果您在一个映射中修改对象(值),那么此修改将反映在第二个映射中。下面的代码展示了如何做到这一点:

    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

    当然,如果您在地图一中添加新元素,那么它们将不会在地图二中看到。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-09
      • 2013-03-19
      • 1970-01-01
      • 1970-01-01
      • 2018-12-26
      相关资源
      最近更新 更多