亲子计划
我正在编写一个类,它保存指向相同类型的父对象的指针(想想 Qt 的 QObject 系统)。每个对象都有一个父对象,当子对象被销毁时,父对象不应该被销毁(显然)。
class MyClass
{
public:
MyClass(const MyClass* ptr_parent): parent(parent){};
~MyClass(){ delete[] a_children; };
private:
const MyClass* ptr_parent; // go to MyClass above
MyClass* a_children; // go to MyClass below
size_t sz_numChildren; // for iterating over a_children
}
(请原谅我的内联编码,这只是为了简洁)
销毁“Master MyClass”会照顾所有孩子吗?任何孩子都不应该能够杀死它的父母,因为这样我的主程序中就会有指向被破坏对象的指针,对吗?
你为什么会问?我需要一种方法来“迭代”所有子目录并在独立于平台的级别上查找所有文件。该树的创建将由本机 API 处理,其余的则不会。这是一个好主意吗?
谢谢!
I'm writing a class that holds a pointer to a parent object of the same type (think Qt's QObject system). Each object has one parent, and the parent should not be destroyed when a child is destroyed (obviously).
class MyClass
{
public:
MyClass(const MyClass* ptr_parent): parent(parent){};
~MyClass(){ delete[] a_children; };
private:
const MyClass* ptr_parent; // go to MyClass above
MyClass* a_children; // go to MyClass below
size_t sz_numChildren; // for iterating over a_children
}
(Excuse my inline coding, it's only for brevity)
Will destroying the "Master MyClass" take care of all children? No child should be able to kill it's parent, because I would then have pointers in my main program to destroyed objects, correct?
Why might you ask? I need a way to "iterate" through all subdirectories and find all files on a platform independent level. The creation of this tree will be handled by native API's, the rest won't. Is this a good idea to start with?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这个概念很好,但是您发布的代码有很多问题(尽管我从您关于“内联编码”的评论中了解到您只是即时编写的而不是从可编译程序中复制它)。
您需要将
a_children
设为MyClass
指针数组,因此它需要具有MyClass**
类型,并且您当添加子项时,需要适当地分配它并重新分配它。delete[] a_children
不会删除子项,而是删除保存指向子项的指针的数组。您必须在MyClass
析构函数中迭代该数组,删除每个子指针,然后删除该数组。事实上,对a_children
使用std::vector
而不是MyClass*
可能是一个更好的主意,所以你不必担心(1)。但即使使用向量,您仍然需要迭代并删除析构函数中的每个子级。您的孩子将需要以某种方式向其父对象“注册”。按照您编写的方式,子对象无法告诉父对象它存在。因此,您可能无法避免传递 const 父指针。
因此,举个例子:
请注意,这并没有考虑到子级将被除摧毁其父级之外的任何方式摧毁的可能性。
This concept is fine, but there are a number of things wrong with the code you posted (although I gather from your comment about "inline coding" that you just wrote this on the fly rather than copying it out of a compilable program).
You will need to have
a_children
be an array ofMyClass
pointers, so it will need to have typeMyClass**
, and you will need to allocate it an reallocate it appropriately as children are added.delete[] a_children
will not delete the children, it will delete the array that holds the pointers to the children. You must, in theMyClass
destructor, iterate over the array, deleting each child pointer, and then delete the array. In fact, it would probably be a better idea to use astd::vector<MyClass*>
fora_children
instead ofMyClass*
, so then you don't have to worry about (1). But even with a vector, you will still need to iterate and delete each child in the destructor.Your children will need to "register" with their parent object somehow. The way you have written this, there is no way for the child object to tell the parent object that it exists. For this reason you probably will not be able to get away with passing a const parent pointer.
So, as an example:
Note that this does not take into account the possibility that children will be destroyed by any means other than destroying their parent.
是的,如果您使用以下命令创建子项:
删除父项将依次删除所有子项。
然而,由于一些原因,这不会很灵活。
addChild()
这样的函数。我建议使用指向 MyClass 对象的指针向量来存储子项:
然后您可以根据需要创建子项:
并删除所有子项:
实际的指针向量将被自动销毁。
Yes, if you create the children with:
deleting a parent will in turn delete all children.
However, this will not be very flexible for a few reasons.
addChild()
very easily.I would recommend using a vector of pointers to MyClass objects to store the children:
Then you can create children as needed:
and delete all children with:
The actual vector of pointers will be destroyed automatically.
是的,你如何编码它就会。然而,您可能希望将 a_children 初始化为 NULL 或您预先分配的内存中的某个空间。
只要您考虑到当父级被删除时,父级/子级树外部的某个人拥有指向子级的指针(导致子级被删除)的情况,查找就可以。这会/可以优雅地处理吗?这是您必须关心的情况吗?如果是这样,那么您可能必须考虑悬空指针。
Yes how you have it coded it will. You may however wish to initialize a_children to NULL or to some space in memory you have preallocated.
Seeks ok so long as you have taken into account the case where someone external to your parent/child tree has a pointer to a child when the parent is deleted (resulting in the child being deleted). Will/can this be handled gracefully? Is this a situation you have to be concerned with? If so then you may have to think about dangling pointers.
我不是 C++ 专家,但我认为如果没有为子级分配
new[]
,则删除它们是不明智的。请参阅有关内存分配的 C++ 常见问题解答更多细节。
然而,除此之外,该计划看起来还不错。
I'm not a C++ expert but I don't think it's kosher to
delete[]
the children if they weren't allocated withnew[]
.See the C++ FAQ on memory allocation for more details.
However, otherwise, the plan looks sound.
另一个问题是,您必须确保一个实例不能是多个父级的子级,否则销毁父级也可能会销毁属于另一个父级的子级。在您的示例中,由于硬链接、Windows 连接点等原因,子目录可能是多个父目录的子目录,因此您需要确保在这种情况下每个超级目录都会获得自己唯一的子实例对于该目录。如果子项可以共享,那么您将需要实施某种引用计数方案以防止过早删除。
Another gotcha is that you must make sure that an instance cannot be a child of more than one parent, or else destroying a parent could also destroy children belonging to another parent. In your example, a child directory could be a subdirectory of more than one parent directory due to hard links, Windows junction points or the like, so you need to either make sure that in such a situation each superdirectory would get its own unique child instance for that directory. If children can be shared, then you will need to implement some sort of reference counting scheme to prevent premature deletion.