, Decorator; , ++.
Decorator , . , , BaseDecorator name:
.
++, , , . , , , ++ .
, , ?
, :
class IRecord {
public:
virtual bool lessThan(IRecord const& other) const = 0;
};
, ; , , , this EmailDecorator, EmailDecorator - .
, , :
class RecordDecorator: public IRecord {
protected:
RecordDecorator(std::unique_ptr<IRecord> r): _decorated(std::move(r)) {}
private:
std::unique_ptr<IRecord> _decorated;
};
:
class BaseRecord final: public IRecord {
public:
BaseRecord(std::string name, std::string address):
_name(std::move(name)), _address(std::move(address)) {}
virtual bool lessThan(IRecord const& record) const override;
private:
std::string _name;
std::string _address;
};
, , ( , ) :
class Record {
public:
Record(std::string name, std::string address):
_data(std::make_unique<BaseRecord>(std::move(name), std::move(address)) {}
bool lessThan(Record const& other) const {
return _data->lessThan(other._data);
}
template <typename D, typename... Args>
void decorate(Args&&... args) {
_data = std::make_unique<D>(std::move(_data), std::forward<Args>(args)...);
}
private:
std::unique_ptr<IRecord> _data;
};
:
, , Record ( ), std::unique_ptr .
, virtual std::unique_ptr<IRecord> clone() const = 0 (*) IRecord, . RecordDecorator:
class RecordDecorator: public IRecord {
protected:
RecordDecorator(std::unique_ptr<IRecord> r): _decorated(std::move(r)) {}
RecordDecorator(RecordDecorator const& other):
_decorated(other._decorated->clone()) {}
RecordDecorator& operator=(RecordDecorator const& other) {
if (this == &other) { return *this; }
_decorated = other._decorated.clone();
return *this;
}
RecordDecorator(RecordDecorator&&) = default;
RecordDecorator& operator=(RecordDecorator&&) = default;
private:
std::unique_ptr<IRecord> _decorated;
};
, RecordDecorator, - --, , .
Record :
Record::Record(Record const& other):
_data(other._data.clone())
{}
Record& Record::operator=(Record const& other) {
if (this == &other) { return *this; }
_data = other._data.clone();
return *this;
}
Record::Record(Record&&) = default;
Record& Record::operator=(Record&&) = default;
, :
class EmailDecorator final: public RecordDecorator {
public:
EmailDecorator(std::unique_ptr<IRecord> base, std::string email):
RecordDecorator(std::move(base)), _email(email) {}
virtual std::unique_ptr<IRecord> clone() const override {
return std::make_unique<EmailDecorator>(*this);
}
virtual bool lessThan(IRecord const&) const override;
private:
std::string _email;
};
int main() {
Record record{"John, Doe", "12345 Mimosa Road, 3245 Washington DC"};
record.decorate<EmailDecorator>("john.doe@aol.com");
std::vector<Record> vec;
vec.push_back(record);
vec.back().decorate<EmailDecorator>("doe.john@msn.com");
}
... ... : lessThan .