如何解决在另一个类中使用抽象类对象的C ++设计模式
| 我有一个带有2个纯虚方法的类,另一个类需要使用此类的对象。我想允许此类的用户指定应在其内部使用抽象类的哪个派生。 我正在努力找出正确的方法。struct abstract {
virtual int fst_func() = 0;
virtual void sec_func(int) = 0;
};
// store an instance of \"abstract\".
class user_of_abstract
{
private:
abstract* m_abstract;
public:
// Pass a pointer to an \"abstract\" object. The caller takes care of the memory resource.
user_of_abstract_base(abstract* a) : m_abstract(a) { }
// Pase any type,which needs to be derived from \"abstract\" and create a copy. Free memory in destructor.
template<class abstract_type>
user_of_abstract_base(abstract_type const& a) : m_abstract(new abstract_type(a)) { }
// use the stored member to call fst_func.
int use_fst_func() {
return this->m_abstract->fst_func();
}
// use the stored member to call sec_func.
void use_sec_func(int x) {
this->m_abstract->sec_func(x);
}
};
// use boost::shared_ptr
class user_of_abstract
{
private:
boost::shared_ptr<abstract> m_abstract;
public:
// Pass a pointer to an \"abstract\" object. The caller takes care of the memory resource.
user_of_abstract_base(boost::shared_ptr<abstract> a) : m_abstract(a) { }
// use the stored member to call fst_func.
int use_fst_func() {
return this->m_abstract->fst_func();
}
// use the stored member to call sec_func.
void use_sec_func(int x) {
this->m_abstract->sec_func(x);
}
};
// pass a pointer of an \"abstract\" object wherever needed.
struct user_of_abstract
{
// use the passed pointer to an \"abstract\" object to call fst_func.
int use_fst_func(abstract* a) {
return a->fst_func();
}
// use the passed pointer to an \"abstract\" object to call sec_func.
void use_sec_func(abstract* a,int x) {
a->sec_func(x);
}
};
重要的是要注意,来自sec_func()的参数\“ x \”必须是fst_func()在同一“抽象”实例上返回的值。
编辑:
使用boost :: shared_ptr添加了另一种方法,该方法应具有最大优势。
解决方法
我要说的是,将“ 1”对象传递给用户的构造函数是正确的方法,因为用户的方法依赖于在同一“ 1”对象上调用。我什至会更进一步,使
x
参数成为用户的内部状态,正如您所说的那样,此值是从第一个函数的调用返回的值很重要。
更新:如果您担心使用期限,则可以利用boost中提供的各种智能指针选项。这些应该涵盖大多数使用情况。
, 既然您说第二个函数应该使用第一个函数的输出。我想第一种方法会减少出错的机会。您甚至可以将其修改为以下内容:
int use_fst_func() {
return x=this->m_abstract->fst_func();
}
void use_sec_func() {
this->m_abstract->sec_func(x);
}
protected:
int x;
, 您将自己陷入维护麻烦中。
在第一个示例中...
确实不需要模板构造函数。它被指定为
// Parse any type,which needs to be derived from \"abstract\" and create a copy.
用户已经可以通过自己创建实例并将其传递给第一个构造函数来做到这一点。
此外,与此:
// Free memory in destructor.
您明确地说您不知道应如何使用此类。在编写第一个示例时,您需要决定:使用从外部创建的实例,还是使用从内部创建的实例。看到一个接口,其中一个ctor取得一个指针,而另一个ctor取得一个引用,这两者本质上都是相同的类型,这令人困惑。
在我眼中,使用从外部创建的,不受内存管理的实例或从内部创建的,由内存管理的实例的唯一可接受的方法是,当有一个默认的ctor可以初始化内部指向一个合理值的指针(但是这里似乎不是这种情况,因为您要复制另一个实例):
template <typename T>
class user_of_abstract
{
bool m_owner_;
abstract* m_abstract;
public:
user_of_abstract_base(abstract* a = NULL)
: m_owner(a == NULL),m_abstract(m_owner ? new T(): a)
{
}
~user_of_abstract_base()
{
if (m_owner)
{
delete m_abstract;
}
}
}
你的第二个例子
优于第一个,因为您没有明确地将内存管理与内存引用混合使用。您让shared_ptr
隐式执行。很好,这就是它的用途。
但是,由于您要求ѭ9必须将ѭ10的输出作为输入,因此您离安全问题的解决方法还有很长一段路要走。
例如,如果实例上的ѭ10throw引发异常,而后来又在同一实例上调用use_sec_func
,会发生什么?
您如何期望重要信息“始终在B之前呼叫A。并且仅一次。将A结果传递给B。”应该从现在起两年内传播给该类别的用户?
为什么use_sec_func
不能只叫use_fst_func
?
至于你的第三个例子
您想使用它而不是直接调用实例函数时,可以给出一种方案吗?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。