我对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
答案 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
如果有人有类似问题,希望这会有所帮助。