考虑一个封闭类层次结构如下述:减少对基础样板衍生委托在非虚拟多态类
class B {...};
class D1 final : public B {...};
class D2 final : public B {...};
凡B
是一个抽象的基类和D1
和D2
是它的派生类。
由于实现约束或设计,没有这些类的具有任何virtual
方法,但成员函数上B
在D1
具有不同的实现并D2
简单地通过使衍生的运行时检查委托给实际最派生的类型类型,如下所示:
class B {
bool isD1;
protected:
B(bool isD1) : isD1{isD1} {}
public:
std::string to_string() {
return isD1 ? static_cast<D1*>(this)->to_string() : static_cast<D2*>(this)->to_string();
}
}
class D1 final : public B {
public:
D1() : B(true) {}
std::string to_string() { // D1 specific implementation ... }
}
class D2 final : public B {
public:
D2() : B(false) {}
std::string to_string() { // D2 specific implementation ... }
}
上。这里B
的to_string
方法只检查的B
最派生类型是D1
D2
或并调用适当的方法(也使用C称为to_string
ASES)。
很酷。
现在想象有另外10种方法,如B::to_string
。我可以在C++ 11中做什么来减少B
中的委托样板文件,而不使用宏?
在C++ 14它似乎是一个合理的做法是一个通用的代理机制,如:
class B {
...
template <typename F>
auto delegate(F&& f) -> decltype(f(D1{})) {
return isD1 : f(*static_cast<D1*>(this)) : f(*static_cast<D2*>(this));
}
std::string to_string() {
return delegate([](auto&& b){ return b.to_string(); });
}
}
这里[](auto&& b){ return b.to_string(); }
通用拉姆达作品是否最终通过了D1
或D2
(因为两者具有to_string
方法) 。在C++ 11中,我没有看到用同样简洁的方式表达这一点。
任何想法?当然,你可以使用宏来复制一个非泛型的宏,并将它传递给一个双参数的delegate
方法(对D1
和D2
采用不同的函子),但我想避免使用宏。
这里关闭意味着该组B
派生类的固定和在运行时是已知的。
摘要在概念但不是在 “纯virtual
” 感。那就是这个类不应该直接实例化 - 唯一有意义的整个对象是它的派生类。各种构造函数都制作为protected
来执行此操作。
我是否正确拒绝了基于预处理器宏的解决方案? – lockcmpxchg8b
@ lockcmpxchg8b - 正确。事实上,我已经在使用这样的解决方案,因为编写'DELEGATE(x)'宏很容易,所以'DELEGATE(std :: string,to_string)'简单地扩展到'B :: to_string()'实现如上所示,然后一些其他的宏来处理带参数的函数等。 – BeeOnRope
@BeeOnRope - 我完全误解了这个问题;抱歉。 – max66