static abstract methods in c++
我有一个抽象基类
1 2 3 4 5 | class IThingy { virtual void method1() = 0; virtual void method2() = 0; }; |
我想说:"提供具体实例的所有类也必须提供这些静态方法。"
我很想去做
1 2 3 4 5 6 | class IThingy { virtual void method1() = 0; virtual void method2() = 0; static virtual IThingy Factory() = 0; }; |
我知道这不会编译,而且即使它确实编译了,也不清楚如何使用它。不管怎样,我能做的就是
1 | Concrete::Factory(); // concrete is implementation of ITHingy |
根本没有提到基类中的工厂。
但我觉得应该有某种方式来表达我希望实现能够签署的契约。
这有一个众所周知的成语吗?或者我只是把它写在评论里?也许我不应该强迫你这么做
编辑:当我输入问题时,我会觉得自己很含糊。我只是觉得应该有办法表达它。伊戈尔给出了一个优雅的答案,但事实上,这表明它确实没有帮助。我最终还是不得不这么做
1 2 3 4 5 6 7 8 | IThingy *p; if(..) p = new Cl1(); else if(..) p = new Cl2(); else if(..) p = new Cl3(); etc. |
我猜像C语言、Python或Java这样的反射语言可以提供更好的解决方案。
你所面临的问题部分与轻微违反单一责任原则有关。您试图通过接口强制创建对象。相反,接口应该更纯粹,并且只包含与接口应该做的事情成整数的方法。
相反,您可以将创建从接口(所需的
这里是一个简单的工厂实现,它强制派生类上的工厂方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | template <class TClass, class TInterface> class Factory { public: static TInterface* Create(){return TClass::CreateInternal();} }; struct IThingy { virtual void Method1() = 0; }; class Thingy : public Factory<Thingy, IThingy>, public IThingy { //Note the private constructor, forces creation through a factory method Thingy(){} public: virtual void Method1(){} //Actual factory method that performs work. static Thingy* CreateInternal() {return new Thingy();} }; |
用途:
1 2 3 | //Thingy thingy; //error C2248: 'Thingy::Thingy' : cannot access private member declared in class 'Thingy' IThingy* ithingy = Thingy::Create(); //OK |
通过从
error C2039: 'CreateInternal' : is not
a member of 'Thingy'
静态方法不能在C++中虚拟化(或抽象化)。
要想做你想做的,你可以有一个返回具体实例的
假设您还没有调用工厂的"初始值设定项",您将希望采取适当的操作,例如引发异常。
在C++中没有这样的约定,因为也没有办法使用这种多态性。
1 | Concrete::Factory() |
总是静态编译时的事情,也就是说,您不能在
你可以让客户执行这种"契约",使它比不提供它更方便。例如,您可以使用crtp:
1 2 3 4 5 6 7 8 | class IThingy {...}; template <class Derived> class AThingy : public IThingy { public: AThingy() { &Derived::Factory; } // this will fail if there is no Derived::Factory }; |
并告诉客户机从
或者您可以使用经典的解决方案,创建工厂类的单独层次结构,并要求客户机向您的API提供他们的