在 C++11 中实现虚拟方法条件
implement virtual method conditional in c++11
说实话,我不喜欢虚拟调度,接口类。出于这个原因,我希望在没有任何基本抽象类的情况下实现自己的类。为了图像,我正在实现MyCustomWidget,它的一些方法已经实现,其他方法没有,因为它不是必需的。
// here is my custom widget class, which 'show' method is implemented, but 'close' method is not.
struct MyCustomWidget
{
void show(){ std::cout << "Hey" << std::endl; }
//void close(){ std::cout << "Bye" << std::endl; }
};
// here is your custom widget class, which 'show' is not implemented but 'close' is .
struct YourCustomWidget
{
//void show(){}
void close(){ std::cout << "Bye" << std::endl;}
};
// common widget class, which may stored within any custom widgets.
struct Widget
{
Widget() = default;
template< typename CustomWidget >
void add(CustomWidget cw)
{
auto child = std::make_unique< proxy<CustomWidget> >( std::move( cw ) )
childs.push_back( std::move(child ) );
}
void show()
{
for(auto & e : childs)
e->show();
}
void close()
{
for(auto& e : childs)
e->close();
}
private:
struct proxy_base
{
virtual void show() = 0;
virtual void close() = 0;
virtual ~proxy_base(){}
};
template< typename CustomWidget >
struct proxy : public proxy_base
{
explicit proxy(CustomWidget cw_) : cw( std::move(cw_ ) )
{}
void show() override final
{ // -------------->>>>>> (1)
// call cw.show() if cw has 'show' method, otherwise nothing.
}
void close() override final
{ /// ---------------->>>> (2)
// call cw.close if cw has a 'close' method, otherwise nothing.
}
CustomWidget cw;
};
std::vector< std::unique_ptr< proxy_base > >childs;
};
int main()
{
Widget w;
w.add( MyCustomWidget() );
w.add( YourCustomWidget() );
w.show();
//.... a lot of code
w.close();
}
我的问题很简单:我如何实现(1)和(2)虚拟方法?
编辑:我看到这个问题已经得到了回答。让我改变我的问题。Q2:(1)和(2)方法是"最终的",在基类中它们被声明为纯虚拟,在这种情况下,编译器可以优化虚拟表,并避免它?我对GCC,CLang和Visual Studio 2013很有趣。
您可以将这些放在代理类的private
部分中:
template<typename T>
auto show_helper(int) -> decltype( std::declval<T>().show(), void())
{
cw.show();
}
template<typename T>
void show_helper(...) { }
并从show
这样称呼他们:
show_helper<CustomWidget>(0);
仅当尾随返回类型中的表达式格式正确时,即当T
具有show
方法时,才会实例化第一个重载。
这被称为表达SFINAE,比pmr的答案中的C++11之前的版本短得多。它也更加灵活,因为它可以让您更轻松地指定show
的签名。另一个答案可以给你积极的结果,只是发现你不能在没有参数的情况下调用show
。选择你的毒药。
活生生的例子。
您可以获取 SFINAE 特征类进行检查,然后使用它来调度close_impl
。或者,您也可以将 traits 类与 enable_if
结合使用,以选择正确的close
版本。
#include <iostream>
#include <type_traits>
template <typename T>
class has_close
{
typedef char one;
typedef long two;
template <typename C> static one test( decltype(&C::close) ) ;
template <typename C> static two test(...);
public:
enum { value = sizeof(test<T>(0)) == sizeof(char) };
};
struct X { void close() {} };
struct X1 { };
template<typename T>
struct XX {
T t;
void close() {
close_impl(std::integral_constant<bool, has_close<T>::value>{});
}
void close_impl(std::true_type) { std::cout << "call close" << std::endl;t.close(); }
void close_impl(std::false_type) { std::cout << "no close" << std::endl;}
};
int main()
{
XX<X> x; x.close();
XX<X1> x1; x1.close();
return 0;
}
相关文章:
- 访问条件类成员的方法不仅在被调用时才编译
- 实现基于数字值(正、负、零)的条件表达式的最佳方法
- 如何使用 SFINAE 在方法调用中有条件地定义变量?
- 找到一种使用 C++ 中的条件提取浮点数的方法
- 有没有一种很好的方法来实现具有默认失败情况的条件类型?
- 有条件地删除模板类中的方法
- 此工厂方法是否会导致争用条件?
- 根据编译时条件在类型之间选择类型的惯用方法
- 在C++有没有更好的方法可以做到这一点?检查哪些数字满足条件 [A*B*C = A! + B! + C!]
- 三元条件结果的方法
- C ,最有效的方法将大写速度更改为小写,反之亦然,而无需条件分支
- 有没有更简单的方法在 Rcpp 中使用 NumericVector 编写条件语句
- 使用 gtest EXPECT_CALL 时竞争条件段错误,而另一个期望是执行相同的方法
- 在什么条件下,纯虚拟方法生成了
- 是否有更简单的方法来定义C 中的for循环中的条件
- 在条件上更新变量的最快方法是什么?
- 在 C++11 中实现虚拟方法条件
- 非模板类方法的条件模板专用化
- 是否有 std 或提升容器可以避免其插入和查找方法之间的争用条件
- 有条件地控制 for 循环方向的最佳方法是什么