Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在基类中编写工厂方法 类基{ 公众: 静态std::unique_ptr CreateBase(); } 阶级工厂{ 公众: 静态std::unique_ptr CreateBase(); }_C++ - Fatal编程技术网

C++ 在基类中编写工厂方法 类基{ 公众: 静态std::unique_ptr CreateBase(); } 阶级工厂{ 公众: 静态std::unique_ptr CreateBase(); }

C++ 在基类中编写工厂方法 类基{ 公众: 静态std::unique_ptr CreateBase(); } 阶级工厂{ 公众: 静态std::unique_ptr CreateBase(); },c++,C++,我们可以在基类中声明工厂方法,也可以创建一个单独的类并在其中编写工厂方法。哪一个更好?为什么?两者都不是 您还可以将工厂声明为一个自由函数std::unique\u ptr CreateBase()a.k.a在我非常谦虚的观点中,“create”是一个自然属于工厂的函数。工厂创造了一些东西 它可以以任何方式实现。但我仍然认为它是工厂的一部分 您还可以使用更复杂的解决方案。以非常通用的方式定义要创建的类,并使用混合方法 请参见下面的示例: class Base { public: stat

我们可以在基类中声明工厂方法,也可以创建一个单独的类并在其中编写工厂方法。哪一个更好?为什么?两者都不是


您还可以将工厂声明为一个自由函数
std::unique\u ptr CreateBase()
a.k.a

在我非常谦虚的观点中,“create”是一个自然属于工厂的函数。工厂创造了一些东西

它可以以任何方式实现。但我仍然认为它是工厂的一部分

您还可以使用更复杂的解决方案。以非常通用的方式定义要创建的类,并使用混合方法

请参见下面的示例:

class Base {
 public:
   static std::unique_ptr<Base> CreateBase();
}

class Factory {
public:
  static std::unique_ptr<Base> CreateBase();
}

#包括
#包括
#包括
#包括
//一些演示课程----------------------------------------------------------------------------------
结构基{
基(int d):数据(d){};

virtual~Base(){std::cout第一个应该是静态方法。@Someprogrammerdude更正了。在更完整的示例中,您应该在factory方法中基于某个参数(例如字符串)构造子对象。不用说,你不应该用派生类的信息污染基类,所以不要把方法放在那里。第一个选项要求
base
知道从它派生的类,这通常是个坏主意。
#include <iostream>
#include <map>
#include <utility>
#include <any>


// Some demo classes ----------------------------------------------------------------------------------
struct Base {
    Base(int d) : data(d) {};
    virtual ~Base() { std::cout << "Destructor Base\n"; }
    virtual void print() { std::cout << "Print Base\n"; }
    int data{};
};
struct Child1 : public Base {
    Child1(int d, std::string s) : Base(d) { std::cout << "Constructor Child1 " << d << " " << s << "\n"; }
    virtual ~Child1() { std::cout << "Destructor Child1\n"; }
    virtual void print() { std::cout << "Print Child1: " << data << "\n"; }
};
struct Child2 : public Base {
    Child2(int d, char c, long l) : Base(d) { std::cout << "Constructor Child2 " << d << " " << c << " " << l << "\n"; }
    virtual ~Child2() { std::cout << "Destructor Child2\n"; }
    virtual void print() { std::cout << "Print Child2: " << data << "\n"; }
};
struct Child3 : public Base {
    Child3(int d, long l, char c, std::string s) : Base(d) { std::cout << "Constructor Child3 " << d << " " << l << " " << c << " " << s << "\n"; }
    virtual ~Child3() { std::cout << "Destructor Child3\n"; }
    virtual void print() { std::cout << "Print Child3: " << data << "\n"; }
};



using UPTRB = std::unique_ptr<Base>;


template <class Child, typename ...Args>
UPTRB createClass(Args...args) { return std::make_unique<Child>(args...); }

// The Factory ----------------------------------------------------------------------------------------
template <class Key, class Object>
class Factory
{
    std::map<Key, std::any> selector;
public:
    Factory() : selector() {}
    Factory(std::initializer_list<std::pair<const Key, std::any>> il) : selector(il) {}

    template<typename Function>
    void add(Key key, Function&& someFunction) { selector[key] = std::any(someFunction); };

    template <typename ... Args>
    Object create(Key key, Args ... args) {
        if (selector.find(key) != selector.end()) {
            return std::any_cast<std::add_pointer_t<Object(Args ...)>>(selector[key])(args...);
        }
        else return nullptr;
    }
};

int main()
{
    // Define the factory with an initializer list
    Factory<int, UPTRB> factory{
        {1, createClass<Child1, int, std::string>},
        {2, createClass<Child2, int, char, long>}
    };

    // Add a new entry for the factory
    factory.add(3, createClass<Child3, int, long, char, std::string>);


    // Some test values
    std::string s1(" Hello1 "); std::string s3(" Hello3 ");
    int i = 1;  const int ci = 1;   int& ri = i;    const int& cri = i;   int&& rri = 1;

    UPTRB b1 = factory.create(1, 1, s1);
    UPTRB b2 = factory.create(2, 2, '2', 2L);
    UPTRB b3 = factory.create(3, 3, 3L, '3', s3);

    b1->print();
    b2->print();
    b3->print();
    b1 = factory.create(2, 4, '4', 4L);
    b1->print();
    return 0;
}