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

C++:抽象类中需要静态函数

  •  0
  • OldMcFartigan  · 技术社区  · 11 年前

    我正在尝试编写一个c++抽象类,但我不知道如何要求这个类的实现者包含一个静态函数。

    例如:

    class AbstractCoolThingDoer
    {
        void dosomethingcool() = 0; // now if you implement this class 
                                            // you better do this
    }
    
    class CoolThingDoerUsingAlgorithmA: public AbstractCoolthingDoer
    {
        void dosomethingcool()
        {
            //do something cool using Algorithm A
        }
    }
    
    class CoolThingDoerUsingAlgorithmB: public AbstractCoolthingDoer
    {
        void dosomethingcool()
        {
            //do the same thing using Algorithm B
        }
    }
    

    现在,我想做一件很酷的事,但不想详细说明如何做。所以我想做一些类似的事情

    AbstractCoolThingDoer:dosomethingcool();
    

    而不需要知道酷的东西是如何完成的,但这似乎需要一个虚拟和静态的函数,这当然是矛盾的。

    其理由是CoolThingDoerUsingAlgorithmB可能会在稍后编写,希望需要做一些很酷的事情的软件不必重写。

    编辑:不确定我是否清楚自己要完成什么。我有三个想要满足的标准

    1. 一个使用抽象coolingdoor的库,永远不需要重写,即使编写了另一个库从未听说过的coolingdoer。

    2. 如果您试图编写一个不符合所需结构的coolingdoor,那么使用该库的可执行文件将无法编译。

    3. coolingdoor有一些必需的静态函数。

    我可能在追求一个糟糕的设计,所以请给我指一个更好的。我需要一个工厂吗?

    2 回复  |  直到 11 年前
        1
  •  3
  •   lapk    11 年前

    也许,这样的东西会有所帮助(参见 ideone.com example ):

    #include <iostream>
    
    class A
    {
     protected:
      virtual void do_thing_impl() = 0;
     public:
      virtual ~A(){}
      static void do_thing(A * _ptr){ _ptr->do_thing_impl(); }
    };
    
    class B : public A
    {
     protected:
      void do_thing_impl(){ std::cout << "B impl" << std::endl; }
    };
    
    class C : public A
    {
     protected:
      void do_thing_impl(){ std::cout << "C impl" << std::endl; }
    };
    
    int main() 
    {
     B b_;
     C c_;
    
     A::do_thing(&b_);
     A::do_thing(&c_);  
    
     return (0);
    }
    

    编辑:在我看来,OP不需要运行时多态性,而是编译时多态性而不需要类实例(使用 static 函数(当实现隐藏在派生类中时,不需要实例)。希望下面的代码能帮助解决问题( example on ideone.com ):

    #include <iostream>
    
    template <typename Derived>
    struct A
    {
      static void do_thing() { Derived::do_thing(); }
    };
    
    struct B : public A<B>
    {
      friend A<B>;
     protected:
      static void do_thing() { std::cout << "B impl" << std::endl; }
    };
    
    struct C : public A<C>
    {
      friend A<C>;
     protected:
      static void do_thing() { std::cout << "C impl" << std::endl; }
    };
    
    int main() 
    {
     A<B>::do_thing();
     A<C>::do_thing();
    
     return (0);
    }
    

    编辑#2:为了在编译时强制失败,以防用户不遵守所需的模式,以下是 slight modification at ideone.com :

    #include <iostream>
    
    template <typename Derived>
    struct A
    {
      static void do_thing() { Derived::do_thing_impl(); }
    };
    
    struct B : public A<B>
    {
      friend A<B>;
     protected:
      static void do_thing_impl() { std::cout << "B impl" << std::endl; }
    };
    
    struct C : public A<C>
    {
      friend A<C>;
     protected:
      static void do_thing_impl() { std::cout << "C impl" << std::endl; }
    };
    
    struct D : public A<D>
    {
     friend A<D>;
    };
    
    int main() 
    {
     A<B>::do_thing();
     A<C>::do_thing();
     A<D>::do_thing(); // This will not compile.
    
     return (0);
    }
    
        2
  •  0
  •   4pie0    11 年前

    在我看来,这是一个合适的实施地点 bridge pattern 。也许这就是你(无意识地)愿意实现的目标。简而言之,您指定了一个接口及其实现,然后调用 do_thing 方法依次调用指向实现类的指针上的实现。

    C++ example