不推荐使用隐式转换运算符。在 C++11 中,您不仅可以将关键字添加explicit
到单参数构造函数,还可以添加到转换运算符。对于 C++03 代码,您可以使用显式命名的转换函数,例如self()
或down_cast()
。
此外,您似乎正在使用Base
CRTP 类,即启用静态多态性。这意味着您必须在编译时Derived
知道您正在调用哪个特定类。const Base&
因此,除了实现 CRTP 接口外,您不必在任何公共代码中使用引用。
在我的项目中,我有一个类模板enable_crtp
:
#include <type_traits>
#include <boost/static_assert.hpp>
template
<
typename Derived
>
class enable_crtp
{
public:
const Derived& self() const
{
return down_cast(*this);
}
Derived& self()
{
return down_cast(*this);
}
protected:
// disable deletion of Derived* through Base*
// enable deletion of Base* through Derived*
~enable_crtp()
{
// no-op
}
private:
// typedefs
typedef enable_crtp Base;
// cast a Base& to a Derived& (i.e. "down" the class hierarchy)
const Derived& down_cast(const Base& other) const
{
BOOST_STATIC_ASSERT((std::is_base_of<Base, Derived>::value));
return static_cast<const Derived&>(other);
}
// cast a Base& to a Derived& (i.e. "down" the class hierarchy)
Derived& down_cast(Base& other)
{
// write the non-const version in terms of the const version
// Effective C++ 3rd ed., Item 3 (p. 24-25)
return const_cast<Derived&>(down_cast(static_cast<const Base&>(other)));
}
};
此类由任何 CRTP 基类 ISomeClass 私有派生,如下所示:
template<typename Impl>
class ISomeClass
:
private enable_crtp<Impl>
{
public:
// interface to be implemented by derived class Impl
void fun1() const
{
self().do_fun1();
}
void fun2()
{
self().do_fun2()
}
protected:
~ISomeClass()
{}
};
各种派生类可以以自己的特定方式实现此接口,如下所示:
class SomeImpl
:
public ISomeClass<SomeImpl>
{
public:
// structors etc.
private:
// implementation of interface ISomeClass
friend class ISomeClass<SomeImpl>;
void do_fun1() const
{
// whatever
}
void do_fun2()
{
// whatever
}
// data representation
// ...
};
外部代码调用fun1
将class SomeImpl
被委托给适当的 const 或非 const 版本,self()
并且class enable_crtp
在 down_casting 之后do_fun1
将调用实现。使用一个体面的编译器,所有的间接都应该被完全优化掉。
ISomeClass
注意:受保护的析构函数enable_crtp
使代码对试图SomeImpl*
通过基指针删除对象的用户安全。