首页 文章

包含对其他对象的引用的对象的深层副本

提问于
浏览
2

我有一个"sum"类,它拥有对现有int的两个引用(比方说) . 我想创建一个深度复制整数的"copy"方法 . 由于智能指针,我以为我永远不会在我的代码中手动 delete 对象,但我不得不在这个解决方案中 . 而且,对于如此微不足道的任务来说太复杂了(我需要为几个 class 重复这个任务) . 有更简单的解决方案吗?

注意:我不是't want to add a bool member (flag) to each objects to determine if the ints must be deleted (in my case, it'并不比析构函数中的 std::set 检查开销更好

#include <set>

struct sum {
   const int &a, &b;
   static std::set<const int*> allocated_ints;

   sum(const int& a, const int&b): a(a), b(b) {}

   sum copy() const {
       sum res(*new const int(a), *new const int(b));
       allocated_ints.insert(&res.a);
       allocated_ints.insert(&res.b);
       return res;
   }

   ~sum() {
       if (allocated_ints.count(&this->a)) {
           delete &this->a;
           delete &this->b;
           allocated_ints.erase(&this->a);
           allocated_ints.erase(&this->b);
       }
   }

};

std::set<const int*> sum::allocated_ints;

3 回答

  • 0

    "deep"常量副本有什么意义?无论如何,常数都将具有相同的值!所以只需复制(即别名)const-references:

    struct Foo
    {
      const int & n;
    
      Foo(const int & m) : n(m) { }
      Foo(const Foo & rhs) : n(rhs.n) { }
    
      Foo copy() const { Foo f(*this); /* ... */ return f; }
      // ...
    };
    

    如果您担心从引用局部变量的函数返回副本时悬挂引用,则不要使该类具有const引用,而是复制 . 这样你就可以自然地为你的 class 提供你似乎无论如何都要复制的复制语义 .

    如果你认为你可以根据你的使用方式制作一个非拥有或变成拥有的混合动力,那么我会说你应该避免这种糟糕的设计 . 确定您的 class 是否拥有数据的所有权,然后随之滚动 .

  • 2

    我认为你混淆了两个不相容的概念 .

    如果通过引用初始化,则应引用其生命周期已定义且应该比对象长的现有对象 .

    如果你想创建一个对象的副本,因为它引用了某些东西,你的副本也会引用那个东西 .

    如果你想拥有自己动态提供的对象,你应该使用指针,并将它们作为指针获取(并在销毁时删除它们) . 然后,副本可以深度创建指向对象的副本(或者可以使用引用计数或shared_ptr共享它们) .

    事实上,你正在混合这两件事,导致可能的问题:想到:

    int main()
    {
        const int x=5; //whatever it is
        Foo foo(x);
        // ...
    } //danger here! ~Foo() will delete x
    
  • 1

    引用不会被深层复制,因为它们指向一个对象 . 因此,您修复的代码应如下所示:

    struct sum {
       const int &a, &b;
    
       sum(const int& a, const int&b): a(a), b(b) {}
    
       sum copy() const {
           sum res(a,b);
           return res;
       }
    
       ~sum() {
       }
    
    };
    

相关问题