通过C ++中的remove方法自删除对象

时间:2018-06-09 19:45:35

标签: c++ software-design

如何改进代码的架构?我觉得通过调用void remove() { delete this; }方法删除对象的想法有问题。

我的程序中有对象的层次结构(我称之为 hierarchy1 )。层次结构中的每个对象都可以包含其他类的一个或多个对象。例如:

class A { std::vector<std::unique_ptr<B>> bs; };
class B { std::unique_ptr<C> c; };
class C { std::unique_ptr<D> d; std::vector<std::unique_ptr<E>> es; };
class D {};
class E {};

我也有正交层次结构(我称之为 hierarchy2 )。它是对象的层次结构,它不包含任何数据,而是表现为一些带有数据的基本对象。此层次结构中对象之间的连接是通过 signal / slot 模式建立的。例如:

class C { 
    std::unique_ptr<D> d; std::vector<std::unique_ptr<E>> es;
    Signal changed;
    void change(); // somehow changes data and emits signal changed
};
class D { 
    Signal changed;
    void change(); // somehow changes data and emits signal changed
}; 
class C1 { 
    C1(C* c) { c->changed.connect(this, &C1::change); }; 
    Signal changed;
    void change(); // updates its local state based on changes in class C and emits own "changed" signal
}
class C1D {
    C1D(C1* c1, D* d) {
        c1->changed.connect(this, &C1D::change);
        d->changed.connect(this, &C1D::change);
    }; 
    Signal changed;
    void change(); // updates its local state based on changes in class C1 and/or D and emits own "changed" signal
}

这个层次结构非常有效,因为我可以在任何类中启动任何修改,它首先会在层次结构2中向下(例如从C1到C),然后它会上升,更新所有表示(依赖于C)。

当我开始考虑删除对象时,对架构正确性的唯一怀疑就出现了。我想做的基本上与修改相同,所以代替功能和信号对&#34;改变&#34;我介绍了函数和信号对&#34;删除&#34;。所以我的想法是,当我调用例如c1->remove()时,它应该将请求传递给C类,此时C类将启动信号强制删除其每个表示(C1,C1D),最后是类C会要求其父B重置std::unique_ptr<C> c;因此导致自我毁灭。

如何改进此架构?我相信当我有一个指向对象C* c = ...的指针,调用c->remove()时,它不是常见的模式,对象实际上已被破坏,并且无法使用指针。

1 个答案:

答案 0 :(得分:2)

  

如何改进此架构?我相信当我有一个指向对象C * c = ...的指针时,它不是常见的模式,调用c-&gt; remove(),实际上会破坏对象并且不能使用指针。

该对象一直存在,直到析构函数返回,因此当 in 析构函数时,您仍然可以使用它。以下是完全合法的:

class C 
{
  Signal destroyed (C *);

  ~C() 
  {
    destroyed (this);
  }
}

Qt做到了(它有一个destroy()信号)我用这种方式编写了自更新树结构。

但有两条评论:

  • 为什么在C ++有完全合法的方法来删除delete操作符来创建一个remove()函数?
  • 如果你必须有一个函数,我建议调用它destroy()而不是remove();后者建议从名单等中删除,而不是实际破坏。