复合图案:浅复制和深复制

时间:2020-03-23 13:45:14

标签: c++

我对C ++中的复合模式对象上的浅层复制和深层复制有疑问。

这是我用于测试的基本源代码。

https://de.wikipedia.org/wiki/Kompositum_(Entwurfsmuster)

#include<iostream>
#include<set>
#include<string>


class Component {
public :
    void setName(std::string name_) {
        name = name_;
    }   
    std::string getName() {
        return name;
    }


    virtual void print() const = 0;
    virtual ~Component() {}
public: 
    std::string name;
};

class Composite : public Component {
    std::set<Component const*> children;
    typedef std::set<Component const*>::const_iterator grIter;

public: 


    void print() const {

        std::cout << "Type:node: " << name << " memory address: " << this <<std::endl;

        for (grIter it = children.begin(); it != children.end(); it++)
            (*it) -> print();
    }

    void add(Component const* componet_) {
        children.insert(componet_);
    }
    void remove(Component const* componet_) {
        children.erase(componet_); 
    }
};

class Leaf: public Component {
public:
    void print() const {
        std::cout << "Type:Leaf: " << name << " memory address: " << this << std::endl;
    }
};

Composite* helpFunction() {
    Leaf* leaf1, * leaf2, * leaf3, * leaf4;
    leaf1 = new Leaf();
    leaf2 = new Leaf();
    leaf3 = new Leaf();
    leaf4 = new Leaf();

    Composite* node1, * node2, * root;

    node1 = new Composite();
    node2 = new Composite();
    root = new Composite();

    leaf1->setName("leaf1");
    leaf2->setName("leaf2");
    leaf3->setName("leaf3");
    leaf4->setName("leaf4");

    node1->setName("node1");
    node2->setName("node2");

    root->setName("root");

    node1->add(leaf1);
    node1->add(leaf2);
    node1->add(leaf3);

    node2->add(leaf4);

    root->add(node1);
    root->add(node2);

    root->print();

    return root;
}

int main() {

Composite* mainRoot = helpFunction();

    std::cout << "_______________" << std::endl;
    mainRoot->setName("mainRoot");
    mainRoot->print();
}

输出为:

Type:node: root memory address: 00A5F8A8
Type:node: node2 memory address: 00A5F538
Type:Leaf: leaf4 memory address: 00A429E0
Type:node: node1 memory address: 00A5F850
Type:Leaf: leaf2 memory address: 00A42710
Type:Leaf: leaf1 memory address: 00A428A0
Type:Leaf: leaf3 memory address: 00A42940
_______________
Type:node: mainRoot memory address: 00A5F8A8
Type:node: node2 memory address: 00A5F538
Type:Leaf: leaf4 memory address: 00A429E0
Type:node: node1 memory address: 00A5F850
Type:Leaf: leaf2 memory address: 00A42710
Type:Leaf: leaf1 memory address: 00A428A0
Type:Leaf: leaf3 memory address: 00A42940

现在,我想构建一个复制构造函数,赋值运算符和一个比较操作,以检查树中是否存在相同的值,但具有不同的内存地址。 我可以使用任何模式来以优雅的方式完成内存管理操作吗?

我想稍后将树对象用作:

root1 = root2 

if(root1==root2){
 cout<<"equal"<<endl;
}

背景是在不同线程之间交换数据(树对象),

Thx

1 个答案:

答案 0 :(得分:0)

我不知道这是否是最优雅的方法,但似乎可行。

#include<iostream>
#include<set>

class Base {
public:
    virtual void print() const = 0;
    virtual ~Base() {} // Abstrakte Klassen, von denen geerbt wird, sollten immer einen virtuellen Destruktor haben

    void setName(std::string name_) {
        name = name_;
    }
    std::string getName() {
        return name;
    }

    virtual Base* clone() const = 0;

public:
    std::string name;
};

class Composite : public Base {
    std::set<Base const*> children;
    typedef std::set<Base const*>::const_iterator grIter;
public:
    void print() const {
        std::cout << "Type:node: " << name << " memory address: " << this << std::endl;

        for (grIter it = children.begin(); it != children.end(); it++) 
            (*it)->print();
    }

    void add(Base const* component) {
        children.insert(component);
    }

    void remove(Base const* component) {
        children.erase(component);
    }

    Composite() {
        #ifdef DEBUG_OUTPUT
            std::cout << "Composite: Construtor" << std::endl;
        #endif
    }

    Composite(const Composite& rhs) {
        #ifdef DEBUG_OUTPUT
            std::cout << "Composite: Copy Construtor" << std::endl;
            std::cout << "Type:node: " << name << " memory address: " << this << std::endl;
        #endif

            name = rhs.name;
            this->children.clear();

        for (grIter it = rhs.children.begin();it != rhs.children.end(); it++) {
            #ifdef DEBUG_OUTPUT
                std::cout << (*it)->name << std::endl;
            #endif

            this->children.insert((*it)->clone());
        }
    }
    virtual Base* clone() const;    
    Composite& operator=(const Composite& rhs);
};

Base* Composite::clone() const
{
    #ifdef DEBUG_OUTPUT
        std::cout << "Composite: Clone" << std::endl;
    #endif 
    Composite *temp = new Composite();
    temp->name = this->name;
    for (grIter it = this->children.begin(); it != this->children.end(); it++) {       
        temp->children.insert((*it)->clone());
    }
    return temp;
}

Composite& Composite::operator = (const Composite& rhs) {

    #ifdef DEBUG_OUTPUT
        std::cout << "Node: Assignment operator" << std::endl;
    #endif

     if (this != &rhs)
    {
        this->name = rhs.name;

        for (grIter it = rhs.children.begin(); it != rhs.children.end(); it++) {
            #ifdef DEBUG_OUTPUT
                        std::cout << (*it)->name << std::endl;
            #endif

            this->children.insert((*it)->clone());
        }
    }

    return *this;
}


class Leaf : public Base {
public:
    void print() const {
        std::cout << "Type:Leaf: " << name << " memory address: " << this << std::endl;
    }

    Leaf() {
        #ifdef DEBUG_OUTPUT
            std::cout << "Leaf: Construtor" << std::endl;
        #endif  
    }

    Leaf(const Leaf & rhs)  {
        #ifdef DEBUG_OUTPUT
            std::cout << "Leaf: Copy Construtor" << std::endl;
        #endif
        name = rhs.name;

    }

    virtual Base* clone() const;
    Leaf& operator=(const Leaf& rhs);
};

Base* Leaf::clone() const
{
    #ifdef DEBUG_OUTPUT
        std::cout << "Leaf: Clone" << std::endl;
    #endif
    return new Leaf(*this);
}

Leaf& Leaf::operator=(const Leaf& rhs) {
    #ifdef DEBUG_OUTPUT
        std::cout << "Leaf: Assignment operator" << std::endl;
    #endif

    if (this != &rhs)
    {
        name = rhs.name;
    }

    return *this;
}



Composite* helpFunctionByPointer() {
    Leaf* leaf1, * leaf2, * leaf3, * leaf4;
    leaf1 = new Leaf();
    leaf2 = new Leaf();
    leaf3 = new Leaf();
    leaf4 = new Leaf();

    Composite* node1, * node2, * root;

    node1 = new Composite();
    node2 = new Composite();
    root = new Composite();

    leaf1->setName("leaf1");
    leaf2->setName("leaf2");
    leaf3->setName("leaf3");
    leaf4->setName("leaf4");

    node1->setName("node1");
    node2->setName("node2");

    root->setName("root");

    node1->add(leaf1);
    node1->add(leaf2);
    node1->add(leaf3);

    node2->add(leaf4);

    root->add(node1);
    root->add(node2);

    root->print();  

    return root;
}



Composite helpFunctionByValue() {
    Leaf* leaf1, * leaf2, * leaf3, * leaf4;
    leaf1 = new Leaf();
    leaf2 = new Leaf();
    leaf3 = new Leaf();
    leaf4 = new Leaf();

    Composite* node1, * node2;
    Composite rootByValue;

    node1 = new Composite();
    node2 = new Composite();   

    leaf1->setName("leaf1");
    leaf2->setName("leaf2");
    leaf3->setName("leaf3");
    leaf4->setName("leaf4");

    node1->setName("node1");
    node2->setName("node2");

    rootByValue.setName("rootByValue");

    node1->add(leaf1);
    node1->add(leaf2);
    node1->add(leaf3);

    node2->add(leaf4);

    rootByValue.add(node1);
    rootByValue.add(node2);

    rootByValue.print();

    return rootByValue;
}




int main() {


    std::cout << "\t\t\t#############################" << std::endl;
    std::cout << "\t\t\t##########Shallow Copy#######" << std::endl;
    std::cout << "\t\t\t#############################" << std::endl;

    Composite* mainRootByPointer = helpFunctionByPointer();
    Composite* mainRoot2ByPointer;

    std::cout << "_______________" << std::endl;
    mainRootByPointer->setName("mainRootByPointer");
    mainRootByPointer->print();

    mainRoot2ByPointer = mainRootByPointer;

    std::cout << "_______________" << std::endl;
    mainRoot2ByPointer->setName("mainRoot2ByPointer");
    mainRoot2ByPointer->print();


    std::cout << "\t\t\t#############################" << std::endl;
    std::cout << "\t\t\t##########DeepCopy###########" << std::endl;
    std::cout << "\t\t\t#############################" << std::endl;

    Composite mainRootByValue, mainRoot2ByValue;

    mainRootByValue = helpFunctionByValue();
    std::cout << "_______________" << std::endl;
    mainRootByValue.print();

    mainRoot2ByValue = mainRootByValue;
    std::cout << "_______________" << std::endl;
    mainRoot2ByValue.print();

    return 0;
}

这是输出。

                       #############################
                       #############################
Type:node: root memory address: 00DAE3B0
Type:node: node1 memory address: 00DADF90
Type:Leaf: leaf3 memory address: 00D92950
Type:Leaf: leaf1 memory address: 00D92E50
Type:Leaf: leaf2 memory address: 00D92EA0
Type:node: node2 memory address: 00DAE098
Type:Leaf: leaf4 memory address: 00D929F0
_______________
Type:node: mainRootByPointer memory address: 00DAE3B0
Type:node: node1 memory address: 00DADF90
Type:Leaf: leaf3 memory address: 00D92950
Type:Leaf: leaf1 memory address: 00D92E50
Type:Leaf: leaf2 memory address: 00D92EA0
Type:node: node2 memory address: 00DAE098
Type:Leaf: leaf4 memory address: 00D929F0
_______________
Type:node: mainRoot2ByPointer memory address: 00DAE3B0
Type:node: node1 memory address: 00DADF90
Type:Leaf: leaf3 memory address: 00D92950
Type:Leaf: leaf1 memory address: 00D92E50
Type:Leaf: leaf2 memory address: 00D92EA0
Type:node: node2 memory address: 00DAE098
Type:Leaf: leaf4 memory address: 00D929F0
                        #############################
                        #############################
Type:node: rootByValue memory address: 007EFBEC
Type:node: node1 memory address: 00DAE148
Type:Leaf: leaf1 memory address: 00D92A90
Type:Leaf: leaf3 memory address: 00DBC710
Type:Leaf: leaf2 memory address: 00DBC7B0
Type:node: node2 memory address: 00DAE1A0
Type:Leaf: leaf4 memory address: 00DBC800
_______________
Type:node: rootByValue memory address: 007EFDE8
Type:node: node1 memory address: 00DADF38
Type:Leaf: leaf2 memory address: 00DBC3A0
Type:Leaf: leaf1 memory address: 00DBC6C0
Type:Leaf: leaf3 memory address: 00DBC990
Type:node: node2 memory address: 00DAE250
Type:Leaf: leaf4 memory address: 00DBC760
_______________
Type:node: rootByValue memory address: 007EFDB4
Type:node: node1 memory address: 00DAE4B8
Type:Leaf: leaf1 memory address: 00DBC080
Type:Leaf: leaf2 memory address: 00DBC210
Type:Leaf: leaf3 memory address: 00DBC3F0
Type:node: node2 memory address: 00DAE510
Type:Leaf: leaf4 memory address: 00DBC0D0

如果有人有类似问题,希望这会有所帮助。

相关问题