代码之家  ›  专栏  ›  技术社区  ›  ark1974

如果类为空,则禁用所有类成员函数

c++
  •  0
  • ark1974  · 技术社区  · 5 年前

    我有一个诊断绘图类以图形方式绘制多线程环境中对象的状态。但当我不在诊断模式下运行时,这会消耗我的CPU周期。我也不想检查每一行的诊断模式。相反,我喜欢将诊断对象声明为空(或通过一些其他成员函数/额外变量),并且所有诊断成员函数都将变得不相关。这可能吗?我不想更改现有的成员函数

    bool dmode = true; // want to avoid this
    class plot{
         void draw();
    };
    
    class foo{
        void something(){
           plot p;
           if(dmode) p.draw(); // don't want the checking as plot objects are littered everywhere.
        }
    };
    

    //dmode将仅在运行时根据我的设置和配置决定

    2 回复  |  直到 5 年前
        1
  •  3
  •   darune    5 年前

    编译时丢弃

    你可以用 constexpr

    constexpr bool dmode = true;
    
    //...
    
      if constexpr (dmode) {
    

    常量表达式 编译时间


    应该注意的是,这是一个 在此之前,您可以使用宏在编译时丢弃代码。


    第三种选择是仅仅依赖于编译器优化(即常量折叠),但是要提供任何保证要困难得多,而且对于调试构建可能不可行(如果是这样的话)。

    运行时解决方案

    假设你 draw virtual -然后您需要以某种方式创建一个非虚函数来粘贴 if 进入。实现这一点的一种方法是将虚拟函数私有化。

    class plot{
    public:
         void draw() {
           if (!dmode) {
               return;
           }
           do_draw();
         }
    private://<-- or protected
         virtual void do_draw() = 0;//rename in all subclasses
    };
    

    然而,这只是解决问题的一种方法——在不了解更多实际情况的情况下,很难说哪种方法更合适。

        2
  •  0
  •   Thomas    5 年前

    你可以在房间里检查 draw() 功能:

    void plot::draw() {
        if (!dmode) {
            return;
        }
        // Do the actual drawing.
    }
    

    plot 一个纯抽象类,提供两个实现, RealPlot NullPlot . 然后创建一个函数 create_plot() 这取决于 dmode 实图 或者 空区

        3
  •  0
  •   bolov    5 年前

    你有选择。以下是其中一些:

    概念-C++ 20

    constexpr bool dmode = true;
    
    class plot
    {
    
    public:
        void draw() requires (!dmode)
        {
            /* actual implementation */
        }
    
        void draw() requires dmode
        {
            // empty
        }
    };
    
    class foo
    {
        void something()
        {
           plot p;
           p.draw();
        }
    };
    

    Constexpr IF—C++ 17

    constexpr bool dmode = true;
    
    class plot
    {
    
    public:
        void draw()
        {
            if constexpr (!dmode)
            {
                /* actual implementation */
            }   
        }
    };
    
    class foo
    {
        void something()
        {
           plot p;
           p.draw();
        }
    };
    

    模板类和别名-C++ 11

    constexpr bool dmode = true;
    
    template <bool Dmode>
    class plot_base
    {
    public:
        void draw()
        {
            /* actual implementation */
        }
    };
    
    template <>
    class plot_base<true>
    {
    public:
        void draw()
        {
            // empty
        }
    };
    
    template <bool Dmode = dmode>
    using plot = plot_base<Dmode>;
    
    class foo
    {
        void something()
        {
           plot<> p;
           p.draw();
        }
    };
    

    Mock(即以上都不是)

    最终(很可能)没有一个解决方案是合适的。在我看来,你想要的是一个嘲弄。那就调查一下。