不建议使用隐式转换运算符。在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:
// 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
将被授权给class enable_crtp
中的self()
的适当const或非const版本,并且在down_casting之后将调用实现do_fun1
。用一个体面的编译器,所有的indirections应该完全被优化。
注意:ISomeClass
和enable_crtp
的受保护的析构函数使代码对试图通过基指针删除对象的用户安全。
相关部分将是重载解析的部分。 – 2012-03-22 09:23:36
如果你幽默我的好奇心 - 你为什么要在'基地'的转换运算符? – 2012-03-22 09:43:24
@ Tony Delroy:1)比明确调用一个类方法更简洁.2)在尝试获取关于CRTPs的一些知识时,我在网络中偶尔发现了这种代码,参见[here](http ://en.wikipedia.org/wiki/Expression_templates)3)发现这种奇怪的行为后,我真的很好奇哪一个应该是正确的:-) – Massimiliano 2012-03-22 09:57:19