新的共享指针和虚拟函数
new, shared pointer & virtual functions
在我的程序中,我面临着另一个困难(我将它们全部存储起来,并在一个burts中提出许多问题:p)。我所拥有的是一个函子——这些函子都是从DuplicateFn
继承的——它有一个虚运算符(),并且每个子函数都应该写出它自己的版本。
现在,其中一个子线程(称为merge)可能不会成功,在这种情况下,它应该尝试一个回退方法。当前这个类看起来像:
class MergeFn : public DuplicateFn {
public:
MergeFn() : FallBack(new SkipFn())
{
}
MergeFn(GMProject const* Out, GMProject const* In, DuplicateFn* f)
: DuplicateFn(Out, In), FallBack(f)
{
}
virtual void operator() (GMProject::pTree& tOut, const GMProject::pTree& tIn) const {
if (!GMProject::isMergeable(tOut.GetName())) {
(*FallBack)(tOut, tIn); //virtual table resolves this to the correct class
} else {
}
}
private:
std::shared_ptr<DuplicateFn> FallBack;
};
我认为问题在这里已经很明显了——在非默认构造函数中,这个方法获取给定参数的所有权。-这不是我想要的:它应该复制该参数并保留其所有权。
现在我尝试了, FallBack(new DuplicateFn(f))
,但是这也不起作用-因为现在有一个编译错误,它试图用纯虚拟方法从类实例化对象。
我该怎么做呢?我必须为每个类型指定一个特定的构造函数吗?-只是为了正确地复制它?还是我必须通过RTTI?我希望有比这两个更好的方法。
编辑要显示如何初始化(和使用)mergeFn:
std::unique_ptr<detail::DuplicateFn> foo;
foo.reset(new detail::MergeFn(this, &Other, DuplicateFns.at(HandleDuplicate)));
DuplicateFns是一个映射,它帮助将用户输入(字符串)转换为函数指针。-或者像现在一样,指向DuplicateFn子类型对象的指针(指针类型为DuplicateFn*)
然后用作回调方法
ProjectTree.combine_if(tree, &SimilarTreeValue, foo.get());
将两棵树合并为一棵-当SimilarTreeValue返回true时,该条目被认为是重复的。如果条目是叶子,则调用第三个形参——我们正在讨论的函子:)。
最简单的解决方案(在我看来)是改变构造函数的签名,要求已经有一个共享指针:
MergeFn(GMProject const * Out,
GMProject const * In,
std::shared_ptr<DuplicateFn> f) /* ... */
第二个选择是用clone()
函数赋予你的整个类层次结构:
struct Base
{
virtual Base * clone() const { return new Base(*this); }
};
struct Der1 : Base
{
virtual Der1 * clone() const { return new Der1(*this); }
};
可以初始化FallBack(f->clone())
。
我个人会选择第一个版本,我也会检查用唯一指针替换共享指针是否可行。
new DuplicateFn(f)
只对函子f
进行切片。
你需要一个克隆函数:
#include <typeinfo>
#include <cassert>
template <class T>
// runtime checked clone function
// T::do_clone() must be accessible to checked_clone
T *checked_clone (const T* that) {
T *p = that->do_clone();
assert (typeid (*p) == typeid (*that));
return p;
}
// clone for an abstract class
#define IMPLEMENT_CLONE_ABSTRACT(Class)
friend Class *checked_clone<Class> (const Class* that);
public:
Class *clone_naked() const {
return checked_clone (this);
}
unique_ptr<Class> clone_unique() const {
return unique_ptr<Class> (checked_clone (this));
}
private:
virtual Class *do_clone() const = 0;
/* end of IMPLEMENT_CLONE_ABSTRACT */
class Base {
IMPLEMENT_CLONE_ABSTRACT(Base)
};
// clone for a concrete class
#define IMPLEMENT_CLONE_CONCRETE(Class)
friend Class *checked_clone<Class> (const Class* that);
public:
Class *clone_naked() const {
return checked_clone (this);
}
unique_ptr<Class> clone_unique() const {
return unique_ptr<Class> (checked_clone (this));
}
private:
virtual Class *do_clone() const {
return new Class (*this);
}
/* end of IMPLEMENT_CLONE_CONCRETE */
class Derived : public Base {
IMPLEMENT_CLONE_CONCRETE(Derived)
};
您可以使用shared_ptr的构造函数,该构造函数接受自定义析构函数并为其传递空函数。例如。
void dontDelete(DuplicateFn *pFn ) {
// Do nothing!
}
class MergeFn : public DuplicateFn {
public:
MergeFn() : FallBack(new SkipFn())
{
}
MergeFn(GMProject const* Out, GMProject const* In, DuplicateFn* f)
: DuplicateFn(Out, In), FallBack(f, dontDelete)
{
}
virtual void operator() (GMProject::pTree& tOut, const GMProject::pTree& tIn) const {
if (!GMProject::isMergeable(tOut.GetName())) {
(*FallBack)(tOut, tIn); //virtual table resolves this to the correct class
} else {
}
}
private:
std::shared_ptr<DuplicateFn> FallBack;
};
- C++无法定义虚拟函数 OUTER 类和头文件
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 尝试将unique_ptrs推送到向量时使用纯虚拟函数错误
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践
- 类型擦除的std::function与虚拟函数调用的开销
- 重写虚拟函数和继承
- 用纯虚拟函数兜圈子
- 为什么使用存储在虚拟方法表中的地址调用虚拟函数的函数会返回垃圾?
- 禁止子函数调用父级的抽象(或虚拟)函数
- 无法在子类中使用虚拟函数C++
- 无法在派生对象上运行虚拟函数
- 我可以调用从 main() 覆盖的虚拟函数吗?
- 在 C++ 中将函数获取和设置为虚拟函数
- 使用在堆栈上创建的对象调用虚拟函数
- 为什么在这种情况下不调用我的虚拟函数实现?
- 在C++中使虚拟函数私有化
- 模板继承类中的虚拟函数
- 为什么构造函数的虚拟函数调用有时有效,但其他调用却无效
- doxygenc++虚拟函数和实现
- 如何从派生类函数中调用虚拟函数