不建议使用隐式转换运算符。在C++11中,您可以将关键字
explicit
添加到单参数构造函数以及转换运算符中。对于C++03代码,您可以使用显式命名的转换函数,例如
self()
或
down_cast()
。
此外,您似乎正在使用
Base
类进行CRTP,即启用静态多态性。这意味着您必须在
编译时知道要调用哪个特定的
Derived
类。因此,在任何公共代码中,除了实现CRTP接口之外,您不应该使用
const Base&
引用。
在我的项目中,我有一个类模板
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:
~enable_crtp()
{
}
private:
typedef enable_crtp Base;
const Derived& down_cast(const Base& other) const
{
BOOST_STATIC_ASSERT((std::is_base_of<Base, Derived>::value));
return static_cast<const Derived&>(other);
}
Derived& down_cast(Base& other)
{
return const_cast<Derived&>(down_cast(static_cast<const Base&>(other)));
}
};
这个类是从任何CRTP基类ISomeClass私有派生的,就像这样:
template<typename Impl>
class ISomeClass
:
private enable_crtp<Impl>
{
public:
void fun1() const
{
self().do_fun1();
}
void fun2()
{
self().do_fun2()
}
protected:
~ISomeClass()
{}
};
各种派生类可以按照自己的特定方式实现这个接口,就像这样:
class SomeImpl
:
public ISomeClass<SomeImpl>
{
public:
private:
friend class ISomeClass<SomeImpl>;
void do_fun1() const
{
}
void do_fun2()
{
}
};
外部代码调用class SomeImpl
的fun1
将被委托给class enable_crtp
中适当的const或non-const版本的self()
,并在向下转换实现do_fun1
后进行调用。通过良好的编译器,所有间接引用应完全优化掉。
注意:ISomeClass
和enable_crtp
的受保护析构函数使代码对试图通过基指针删除SomeImpl*
对象的用户安全。