- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个记录的基类,想使用装饰器添加额外的字段和比较函数,并能够链接装饰器(记录可以有电子邮件,或出生日期,或两者都有,或没有) .我也会有很多这样的装饰器;每个附加字段一个,及其比较功能。完成此操作后,我将使用基类指针将对象添加到 vector 中。
代码如下:
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 中:
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;
}
那么我该如何编写复制构造函数来进行深复制,并能够释放分配的内存呢?我觉得我错过了一些东西,有一种方法可以做到这一点而不必提供复制构造函数吗?
最佳答案
就装饰器而言,您并没有太大的偏差;不幸的是,您在 C++ 方面的差距很大。
在Decorator
方面,您遇到的主要问题是您的接口(interface) 不应该有任何值(value)。否则,就像这里的情况一样,BaseDecorator
对象有 至少 两个 name
字段:
并且您忘记了从基类初始化一个。
就 C++ 而言,不幸的是这变得复杂,因为您没有考虑所有权。在具有垃圾收集器的语言中,您可以偷工减料,但在 C++ 中,这是行不通的。
那么让我们纠正这个问题,我们应该吗?
首先,我们需要一个干净的界面:
class IRecord {
public:
virtual bool lessThan(IRecord const& other) const = 0;
};
我会让您了解如何实际比较两条记录;使用装饰器方法可能并不容易,因为不能保证仅仅因为 this
是一个 EmailDecorator
, other 也有一个 EmailDecorator
某处 在它的链中。
然后,我们可以构建装饰器方法,我们将使用强大的所有权声明来实现:
class RecordDecorator: public IRecord {
protected:
RecordDecorator(std::unique_ptr<IRecord> r): _decorated(std::move(r)) {}
private:
std::unique_ptr<IRecord> _decorated;
};
我们也可以 build 我们的第一 block 石头:
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 BaseRecord
然后,我们最终可以尝试从中创建一个值类(即可以通过值操作的类):
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;
}; // class Record
这个设计是合理的:
但是,就目前而言,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;
}
// These two got disabled when we wrote our own copy constructor
// and copy assignment operator, so let's re-enable them.
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;
}
// These two got disabled when we wrote our own copy constructor
// and copy assignment operator, so let's re-enable them.
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; // up to you ;)
private:
std::string _email;
}; // class EmailDecorator
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); // make a copy
vec.back().decorate<EmailDecorator>("doe.john@msn.com"); // another e-mail!
}
但是...通过装饰添加字段会使这些字段上的任何逻辑都非常尴尬...您很快就会知道痛苦:一旦您尝试实现 lessThan
实际上。
关于C++ 装饰器添加到 std::vector,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22989530/
我有这些 ViewModel:RecordViewModel、ComponentViewModel,其中 RecordViewModel 本质上是几个 ComponentViewModel 的容器。
我正在尝试为我的 Controller 设置一个装饰器。我的目的是在我的应用程序中的所有 Controller 中引入一些常见的行为。 我已将其配置为在 Angular 1.2.x 中工作,但从 1.
我想用角上的时间戳装饰我生成的所有 JFreeCharts。 JFreeChart 框架中是否有一种方法可以在生成图表后在图像上绘制? 编辑:请注意,这些图表是在后台线程中生成并通过 servlet
在grails应用程序中,我想用自定义数据装饰每个日志。当前的需要只是在日志消息前添加当前用户名 我对如何解决此问题有一些想法: -Adding custom field to log4j patte
我有一个form-el,它只是一个容器,必须将所有子元素包装在具有特定类的div 中。我希望允许 from-el 来包装它们,而不是在每个表单元素中重复这个 div 。我可以循环所有元素并将它们包装在
我遵循以下约定来装饰 Python 类中的某些方法。我想知道是否有一些更好的方法可以做到同样的事情。我的方法看起来当然不太好;对原始成员函数的调用看起来一点也不直观。 from threading i
我的 DTO 看起来像这样 public class SomeDTO { public string last_name{ get; set; } public string ac
这可能是一个远景,但 .NET 的灵 active 一直让我惊叹不已,所以开始吧。 我正在开发一个 MVC 应用程序,它需要在一组程序集中搜索派生自公共(public)基类的类类型。 即我有几个程序集
在我正在进行的项目中,我正在按照项目负责人的要求实现开发人员通知系统。它的工作方式是,如果发生前端错误,开发团队会收到一封错误电子邮件。 但是,在我当前的实现中,我似乎有以下循环依赖: $rootSc
我需要一些关于如何取消装饰和装饰 JInternalFrame 的帮助。我的框架类是这样的: package com; import java.awt.BorderLayout; import jav
假设我们有可能需要长时间运行的任务: public class LongRunningTask { public ReturnType doSomething() { ...
我正在尝试创建一个装饰器方法,它将一些默认的生命周期方法添加到 react 组件中。我的目标是向组件中添加一些默认功能,例如,所有组件都应该能够在 componentWillMount 上执行特定操作
我正在尝试将 DBUS 的异步方法调用与 Twisted 的 Deferred 相结合,但我在调整常用的 DBUS 服务方法装饰器来执行此操作时遇到了麻烦。 要使用 DBUS 异步回调方法,您需要:
是否可以设置表格中一行的背景颜色?当条件适用时,我需要突出显示一行。效果为 ...我可以在其中指定“字体”属性。 (我需要突出显示整行)。 最佳答案 您必须子类化 qooxdoo 默认行渲染器才能做到
我正在开发一个具有不同视角的基于 Java Swing 的应用程序。对于“主菜单”视角,我不希望装饰窗口 (JFrame),而在其他视角中,我确实希望装饰窗口。换句话说,我需要动态更 retrofit
我想做一些类似下面代码所示的事情: class foo { private: std::fstream* m_stream; public: foo(std::fstream* str
我的数据源提供了一个 ObservableList ,但是对于我的 ListView,我需要一个 ObservableList . A Warning基本上只是字符串的装饰器,添加一个 boolean
我一直在纠结于装饰+接口(interface)。假设我有以下“行为”接口(interface): interface IFlyable { void Fly();} interface ISwimma
有没有人为 iOS 6 UICollectionView 实现过装饰 View ?不可能 查找有关在网络上实现装饰 View 的任何教程。基本上在我的应用程序中,我有多个部分,我只想在每个部分后面显示
我有一个简单的 Controller ,例如: function MyController($scope, $http) { ... $http.post(url).success(f
我是一名优秀的程序员,十分优秀!