简体   繁体   English

C ++中的工厂模式。 实例化问题

[英]Factory pattern in C++. Issue of instantiation

I have a small Factory class implemented in Java . 我有一个用Java实现的小型Factory class Its minimized version looks like so: 其最小化版本如下所示:

interface MyClass{
    public void doSomething();
}

class Concrete_1 implements MyClass{
    private String field_1;
    Concrete_1(String _field_1){
        // ... initialization
    }
    public void doSomething(){
        // ... not so important
    }
}

class MyClassFactory{
    public static MyClass init(int idx, String val){
        Concrete_1 ex = null;
        switch(idx){
        case 1:
            ex = new Concrete_1(val);
            break;
        default:
            break;
        }
        return ex;
    }
    public static void main(String args[]){
        MyClass ex = MyClassFactory.init(1, "value"); // <-- I like that
    }
}

I like the way it works and especially the way, how I can instantiate particular objects, like: 我喜欢它的工作方式,尤其是如何实例化特定对象的方式,例如:

MyClass ex = MyClassFactory.init(1, "value");

Now what I want is to implement the same thing in C++. 现在,我想要在C ++中实现相同的功能。 I've seen some examples (including some threads at stackoverflow), but in all those examples they use an abstarct class (instead of an interface in my case of Java). 我已经看到了一些示例(包括stackoverflow上的一些线程),但是在所有这些示例中,它们都使用abstarct类(而不是Java的接口)。 And if memory servers me right, it is impossible to create instances of an abstract class. 如果我正确地使用了内存服务器,则不可能创建抽象类的实例。 So, if we simply port the code above to C++ and use some abstract class instead of the interface, it will not work, because this is forbiden: 因此,如果我们仅将上面的代码移植到C ++并使用一些抽象类而不是接口,它将无法正常工作,因为这是被禁止的:

MyClass ex = MyClassFactory.init(1, "value"); // <-- MyClass now is abstract
  // so this is illegal

My question is how can I do exactly the same thing in C++? 我的问题是我该如何在C ++中做完全相同的事情? Thanks! 谢谢!

In C++ it can be reached via pointers: 在C ++中,可以通过指针到达:

struct MyClass{
   virtual void doSomething() = 0;
};

class Concrete_1 : public MyClass {
   String field_1;
public:
   Concrete_1(String _field_1){
    // ... initialization
   };
   void doSomething(){
    // ... not so important
   }
};

class MyClassFactory{
public:
  std::shared_ptr<MyClass> init(int idx, String val){
       switch(idx){
       case 1:
           return std::shared_ptr<MyClass>(new Concrete_1(val));
       }
       return std::shared_ptr<MyClass>();
    }
 };

 int main(...) {
    std::shared_ptr<MyClass> ex = MyClassFactory::init(1, "value"); 
 }

You can use pointers or references for handling those. 您可以使用指针或引用来处理它们。 Eg. 例如。

std::shared_pointer<MyClass> ptrClass = MyClassFactory.init(1, "value");

As Factories in C++ usually returns pointers, then you will probably stick with the pointer option. 由于C ++中的工厂通常返回指针,因此您可能会坚持使用指针选项。 And hint: Do not use raw pointers. 提示:不要使用原始指针。 use shared pointers or unique pointers instead and return shared pointers from Factories. 而是使用共享指针或唯一指针,并从工厂返回共享指针。

More complete solution will be: 更完整的解决方案是:

class MyClassFactory{
    public:
      MyClass* init(int idx, std::string val){
        switch(idx){
        case 1:
            return new Concrete_1;
        default:
            return nullptr;
        }
    }
};

ADDITION 1: 附加1:

About returning type of factory please look at: What is the best smart pointer return type for a factory function? 关于工厂返回类型,请查看: 工厂函数的最佳智能指针返回类型是什么?

people commented about it. 人们对此发表了评论。 I finally left it as non-smart pointer, and wheather it's a good idea or not please look at the link above. 最后,我将其保留为非智能指针,无论是否建议,请查看上面的链接。 In my opinion smart_pointers should be used always, but as you wish. 在我看来,应该始终使用smart_pointers,但是您可以根据需要使用。

The difference between Java and C++ in this case is that in C++ you have to use pointers . 在这种情况下,Java和C ++之间的区别在于,在C ++中,必须使用指针

Create the concrete class using new , and return it as a pointer to the base-class. 使用new创建具体的类,并将其作为指向基类的指针返回。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM