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

发布于 2024-12-10 02:35:38 字数 941 浏览 0 评论 0原文

我有一个“sum”类,其中包含对现有整数的两个引用(比如说)。我想创建一个“复制”方法来深度复制整数。我以为借助智能指针,我永远不必手动删除代码中的对象,但在这个解决方案中我必须这么做。此外,对于如此琐碎的任务来说,它太复杂了(我需要在几节课上重复)。有更直接的解决方案吗?

注意:我不想向每个对象添加 bool 成员(标志)来确定是否必须删除 int(在我的情况下,这并不比 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;

I have a "sum" class which holds two references to existing ints (say). I want to create a "copy" method which deep copies the ints. I thought I would never have to manually delete objects in my code, thanks to smart pointers, but I had to in this solution. Moreover, it is too complicated for a so trivial task (which I need to repeat for several classes). Is there a more straightforward solution?

Note: I don't want to add a bool member (flag) to each objects to determine if the ints must be deleted (in my case, it's not a better overhead than the std::set check overhead in the destructor)

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

半步萧音过轻尘 2024-12-17 02:35:38

常量的“深层”副本有什么意义?无论如何,常数都将具有相同的值!因此,只需复制(即别名)const 引用:

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 引用,而是使用副本。这样你就自然地为你的类提供了你似乎想要的复制语义。

如果你认为你可以制作一个混合体,它要么是非拥有的,要么是拥有的,具体取决于你如何使用它,那么我会说这是你应该避免的糟糕设计。决定你的类是否拥有数据的所有权,然后继续下去。

What's the point of a "deep" copy of constants? The constants are going to have the same value no matter what! So just copy (i.e. alias) the 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; }
  // ...
};

If you're worried about dangling references when returning a copy from a function with a reference to a local variable, then don't make the class have const references, but copies. That way you naturally give your class the copy semantics that you seem to be after anyway.

If you were thinking that you could make a hybrid which is either non-owning or becomes owning depending on how you use it, then I'd say that's bad design that you should avoid. Decide whether your class has ownership over the data or not and then roll with it.

静谧幽蓝 2024-12-17 02:35:38

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

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

如果您想创建对象的副本,因为它引用某个东西,所以您的副本也将引用那个某个东西。

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

事实上,你正在混合这两件事,从而导致可能的问题:思考:

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

I think you're mixing-up two incompatible concepts.

If you initialize by reference you should refer to existing object whose lifetime is already defined and should be longer than your objects.

If you want to create a copy of your object, since it refers to something, your copy will also refer to that something.

If you want to own yourself dynamic supplied objects, you should use pointers for that, and acquire them as pointers (and delete them on destruction). A copy can then deep-create copies of the pointed objects (or can share them using reference counting or shared_ptr).

You are -in fact- making up a mixing of the two things, resulting in possible problems: think to:

int main()
{
    const int x=5; //whatever it is
    Foo foo(x);
    // ...
} //danger here! ~Foo() will delete x
∞琼窗梦回ˉ 2024-12-17 02:35:38

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

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() {
   }

};

The references are not deep copied, because they point to an object. Therefore, your code fixed should look like this :

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() {
   }

};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文