【发布时间】:2014-04-10 13:31:08
【问题描述】:
我有一个记录的基类,并且想要使用装饰器添加额外的字段和比较函数,并且能够链接装饰器(记录可以有电子邮件,或出生日期,或两者兼有,或没有) .我也会有很多这样的装饰器;每个附加字段一个,以及它的比较功能。完成后,我将使用基类指针将对象添加到向量中。
这是代码的概要:
class BaseRecord
{
public:
virtual bool Compare(); // defined elsewhere
protected:
std::string m_strName;
std::string m_strAddress:
};
class BaseDecorator : public BaseRecord
{
public:
BaseDecorator(BaseRecord *pBase) : m_pBase(pBase){}
bool Compare()
{
return m_pBase->Compare();
}
private:
BaseRecord *m_pBase;
};
class EmailDecorator : public BaseDecorator
{
public:
EmailDecorator(BaseRecord *pBase) : EmailDecorator(pBase){}
bool Compare()
{
if (!CompareEmail()) // defined elsewhere
{
return false;
}
BaseDecorator::Compare();
}
private:
std::string m_strEmail
};
class DOBDecorator : public BaseDecorator
{
public:
DOBDecorator(BaseRecord *pBase) : DOBDecorator(pBase){}
bool Compare()
{
if (!CompareDOB()) // defined elsewhere
{
return false;
}
BaseDecorator::Compare();
}
private:
std::string m_strDOB;
};
这些是类。我现在想做的是将它们添加到向量中:
vector<BaseRecord *> m_vecRecords;
BaseRecord pRecord = new BaseRecord();
// wrong - copies pointer only to vector
m_vecRecords.push_back(pRecord);
// OK - default copy constructor for BaseRecord used
m_vecRecords.push_back(new BaseRecord(*pRecord));
// now chain the decorators
// pRecord is a BaseRecord
BaseRecord pRecord = new EmailDecorator(pRecord);
//wrong - copies pointer only to vector
m_vecRecords.push_back(pRecord);
// ??? needs copy constructor
m_vecRecords.push_back(new EmailDecorator(*pRecord));
// pRecord is an EmailDecorator
BaseRecord pRecord = new DOBDecorator(pRecord);
// wrong - copies pointer only to vector
m_vecRecords.push_back(pRecord);
// ??? needs copy constructor
m_vecRecords.push_back(new DOBDecorator(*pRecord));
现在尝试编写复制构造函数:
// should p be an EmailDecorator *, or a BaseDecorator * ?
EmailDecorator::EmailDecorator(const EmailDecorator *p)
{
// this will leak - no delete in the destructor
// I have not supplied a destructor
m_pBase = new BaseDectorator(p);
m_strEmail = p->m_strEmail;
}
// should p be a DOBDecorator *, or BaseDecorator * ?
// in the above example, when the copy constructor is needed, it is an EmailDecorator *
DOBDecorator::DOBDecorator(const DOBDecorator *p)
{
// this will leak - no delete in the destructor
// I have not supplied a destructor
m_pBase = new BaseDectorator(p);
m_strDOB = p->m_strDOB;
}
那么我如何编写复制构造函数来进行深度复制,并能够释放分配的内存?我觉得我错过了一些东西,并且有一种方法可以做到这一点而无需提供复制构造函数?
【问题讨论】:
-
简而言之 - 要深度复制通过基类的指针/引用保存的多态对象,您不仅需要复制构造函数,还需要一个虚拟的
clone()类函数。 -
装饰器模式略有不同,它让基础对象保留一个装饰器列表,需要更多的手动工作,但使用 c++/STL 效果更好
-
Angew - 谢谢,克隆成语是个好主意。
-
sp2danny - 是的,你是对的。我已经重写了我的装饰器,使其具有从基记录继承的基类,然后我所有的具体装饰器都从基装饰器继承。
-
Compare函数与什么比较?
标签: c++ design-patterns decorator stdvector