关于oop:C ++:在抽象类中需要静态函数

C++: Require static function in abstract class

我试图写一个C++抽象类,我不知道如何要求这个类的实现者包含一个静态函数。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
    }
}

现在我想做酷的事情,而不知道酷的事情是如何完成的。所以我想做点什么

1
AbstractCoolThingDoer:dosomethingcool();

不需要知道冷却是如何完成的,但这似乎需要一个既虚拟又静态的函数,这当然是一个矛盾。

其基本原理是,CoolThingDoerusingAlgorithmb可能会在稍后编写,希望需要完成酷工作的软件不必重写。

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

  • 一个使用AbstractCoolThingDoer的库,不需要重写,即使在编写另一个库从未听说过的CoolThingDoer时也是如此。

  • 如果试图编写不符合所需结构的CoolThingDoer,则使用库的可执行文件将不会编译。

  • CoolThingDoer有一些所需的静态函数。

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


    也许,类似这样的事情会有所帮助(参见ideone.com示例):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    #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函数,不需要实例)。希望下面的代码有助于解决此问题(ideone.com上的示例):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    #include <iostream>

    template <typename Derived>
    struct A
    {
      static void do_thing() { Derived::do_thing(); }
    };

    struct B : public A
    {
      friend A;
     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::do_thing();
     A<C>::do_thing();

     return (0);
    }

    编辑2:要在编译时强制失败,以防用户不遵守所需的模式,下面是ideone.com上的轻微修改:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    #include <iostream>

    template <typename Derived>
    struct A
    {
      static void do_thing() { Derived::do_thing_impl(); }
    };

    struct B : public A
    {
      friend A;
     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::do_thing();
     A<C>::do_thing();
     A<D>::do_thing(); // This will not compile.

     return (0);
    }


    在我看来,这是实现桥接模式的正确位置。也许这就是你(无意识地)愿意实现的。简而言之,您指定一个接口及其实现,然后调用您的do_thing方法,然后调用指向实现者类的指针上的实现。

    C++实例