动态树型对象的拷贝构造

1 篇文章 0 订阅
这篇博客介绍了如何在UI开发中处理动态添加属性的对象,通过树形结构组织这些对象,并提供了C++代码示例来实现树形对象的深拷贝。博主展示了如何通过递归实现拷贝,并且详细解释了析构和删除子节点的过程,确保了内存管理的正确性。此外,还展示了如何遍历展示树形结构中的所有节点。
摘要由CSDN通过智能技术生成

进行UI开发的过程中,考虑到用户可能会动态的向一个对象添加属性,或其他对象,可以通过树形结构来组织这个对象,所有可进行添加的对象都应该继承自一个父类。由于树形结构具有无限拓展的特性,拷贝树形对象变得麻烦,所以可以通过递归树来拷贝一个树形对象。

具体实现demo见代码:

#include <iostream>
#include <vector>
using namespace std;
//树形基类
class Node {
public:
    Node() {}
    //虚析构
    virtual ~Node() {
        for (int i = 0; i < NodeArray.size(); i++) {
            delete NodeArray[i];//析构节点
            //这里还要把 NodeArray[i] 从 NodeArray 中移除,以防影响递归
            NodeArray[i] = nullptr;
        }
    }
    string Name;
    //节点数组
    vector<Node*> NodeArray;
    //添加节点
    void AddChild(Node*child) {
        NodeArray.push_back(child);
    }
    void RemoveChild(Node* child) {
        //erase
        for (int i = 0; i < NodeArray.size(); i++) {
            if (NodeArray[i] == child) {
                NodeArray.erase(NodeArray.begin() + i);
                break;
            }
        }

    }
    void DeleteChild(Node* child) {
        //delete        
        for (int i = 0; i < NodeArray.size(); i++) {
            if (NodeArray[i] == child) {
                delete child;
                NodeArray.erase(NodeArray.begin() + i);
                break;                
            }
        }
    }
};

//三个继承了Node的子类
class foo :public Node {
public:
    foo(string name) {
        Name = name;
    }
};
class foo1 :public Node {
public:
    foo1(string name) {
        Name = name;
    }
};
class foo2 :public Node {
public:
    foo2(string name) {
        Name = name;
    }
};

//用已有的树形结构递归构造新的树形结构
void ConstructNode(Node * innode,Node*outnode) {
    for (int i = 0; i < innode->NodeArray.size(); i++) {
        Node* parent = innode->NodeArray[i];
        Node* childnode = nullptr;

        //将 if else 用 函数指针map代替
        if (parent->Name == "foo") {
            childnode = new foo("foo");
            outnode->AddChild(childnode);
        }
        else if (parent->Name == "foo1") {
            childnode = new foo1("foo1");
            outnode->AddChild(childnode);
        }
        else if (parent->Name == "foo2") {
            childnode = new foo2("foo2");
            outnode->AddChild(childnode);
        }
        //递归调用
        ConstructNode(innode->NodeArray[i], childnode);
    }
}
//显示节点
void ShowNode(Node* innode) {
    for (int i = 0; i < innode->NodeArray.size(); i++) {
        Node* node = innode->NodeArray[i];
        cout << node->Name << endl;
        ShowNode(innode->NodeArray[i]);
    }
}

int main()
{
    Node* node = new Node();
    node->AddChild(new foo("foo"));
    node->AddChild(new foo1("foo1"));
    node->AddChild(new foo2("foo2"));

    foo2* f = new foo2("foo2");
    f->AddChild(new foo("foo"));
    f->AddChild(new foo1("foo1"));
    f->AddChild(new foo2("foo2"));

    node->AddChild(f);

    Node* node2 = new Node();
    ConstructNode(node, node2);
    ShowNode(node);
    delete node;

    cout << "---------------------------\n";

    ShowNode(node2);

    delete node2;
}

虚析构是为了析构子对象,

由于树形对象具有析构子节点的能力,析构树时可以从任意节点开始析构,析构后要从数组中把对应的节点移除

移除子节点而不析构的话,把对应子节点的指针设为 nullptr,移除后要从数组中把对应的节点移除。当然前提是能自由访问到每个节点,否则子节点就访问不到了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值