组合模式主要是将所有类型元素都抽象成组件,有的组件是叶子节点(不能再有字节点),有的节点是分支节点(可以有孩子节点)。这样的递归的数据结构很方便管理。
#include <iostream>
#include <exception>
#include <string>
#include <vector>
using namespace std;
class unImplement : public exception {
public:
explicit unImplement(const string &str) : errorMessage(str) {}
const char *what() const noexcept override {
return errorMessage.c_str();
}
private:
string errorMessage;
};
class Composite {
public:
virtual ~Composite() = default;
virtual void print(ostream &os) const = 0;
virtual void append(Composite *composite) {
delete(composite);
throw unImplement(__PRETTY_FUNCTION__);
}
virtual void append(double d) {
throw unImplement(__PRETTY_FUNCTION__);
}
virtual Composite* clone() const = 0;
friend ostream &operator<<(ostream &os, const Composite &composite) {
composite.print(os);
return os;
}
virtual operator double&() {
throw unImplement(__PRETTY_FUNCTION__);
}
virtual Composite &operator=(double d) {
throw unImplement(__PRETTY_FUNCTION__);
}
};
class CompositeLeaf : public Composite {
public:
explicit CompositeLeaf(double data) : data(data) {
cout << "construct leaf " << this << endl;
}
~CompositeLeaf() override {
cout << "delete leaf " << this << endl;
}
CompositeLeaf(const CompositeLeaf& another) : data(another.data) {
cout << "copy construct leaf " << this << " from " << &another << endl;
}
void print(ostream &os) const override {
os << data;
}
Composite *clone() const override {
return new CompositeLeaf(*this);
}
operator double&() override {
return data;
}
CompositeLeaf &operator=(double d) override {
data = d;
return *this;
}
private:
double data;
};
class CompositeList : public Composite {
public:
CompositeList() {
cout << "construct list " << this << endl;
}
~CompositeList() override {
for (auto composite : data)
delete(composite);
cout << "delete list " << this << endl;
}
CompositeList(const CompositeList& another) {
cout << "copy construct list " << this << " from " << &another << endl;
data.reserve(another.data.size());
for (auto composite : another.data)
data.push_back(composite->clone());
}
CompositeList &operator=(const CompositeList& another) {
if (this == &another)
return *this;
for (auto composite : data) {
delete (composite);
}
data.clear();
data.reserve(another.data.size());
for (auto composite : another.data)
data.push_back(composite->clone());
return *this;
}
void append(Composite* composite) override {
data.push_back(composite);
}
void append(double d) override {
data.push_back(new CompositeLeaf(d));
}
Composite &operator[](int i) {
return *data.at(i);
}
void print(ostream &os) const override {
os << "[";
for (auto &leaf : data) {
os << *leaf << ", ";
}
if (!data.empty())
os << "\b\b";
os << "]";
}
Composite *clone() const override {
return new CompositeList(*this);
}
private:
vector<Composite*> data;
};
int main()
{
CompositeList list;
list.append(1);
list.append(2);
list.append(3);
list.append(new CompositeList);
list[3].append(1);
cout << list << endl;
cout << "===============" << endl;
CompositeList list1(list);
cout << list1 << endl;
list1[0] = 1.1;
cout << list << endl;
cout << list1 << endl;
cout << "===============" << endl;
CompositeList list2;
list2.append(new CompositeList);
list2 = list;
cout << list2 << endl;
list2[0] = 1.1;
cout << list << endl;
cout << list2 << endl;
return 0;
}
组件模式稳定部分是Composite
,易变部分是CompositeList/CompositeLeaf
。