针对以下情况的设计模式

时间:2015-01-22 11:32:25

标签: c++ design-patterns factory

我有一些代码:

class Base {
    virtual bool acceptsData(char*) = 0;
};

class Derived1 : public Base {
    virtual bool acceptsData(char*) { /* do something */ }
};

class Derived2 : public Base {
    virtual bool acceptsData(char*) { /* do something else */}
}

Base* createStuff(char* data)
{
    Base* d1 = new Derived1();
    if(d1->acceptsData(data))
    {
          return d1;
    }
    delete d1;

    Base* d2 = new Derived2();
    if(d2->acceptsData(data))
    {
          return d2;
    }
    delete d2;
     // and more ...
}
// .... somewhere later
int main()
{
    Base* Aclass = createStuff("abc");
}

我想摆脱这个长if() ...构造,并使用一些更通用的模式,但我仍然没有经理想出一些有用的东西。有没有更好的方法呢?

3 个答案:

答案 0 :(得分:4)

如果您想要分解代码,因为您有几个派生类,您可以使用以下内容:

namespace detail
{
    template <typename T> std::unique_ptr<Base> make_base(const char* data)
    {
        std::unique_ptr<Base> base = std::make_unique<T>();
        if (base->acceptsData(data)) {
            return base;
        }
        return nullptr;
    }

    template <typename... Ts> std::unique_ptr<Base> createStuff(const char* data)
    {
        std::function<std::unique_ptr<Base>(const char*)> fs[] = { make_base<Ts>... };

        for(auto& f : fs) {
            auto base = f(data);
            if(base) {
                return base;
            }
        }
        return nullptr;
    }
}

Base* createStuff(const char* data) {
    return detail::createStuff<Derived1, Derived2/* and other Derived classes*/>(data).release();
}

Live example

答案 1 :(得分:0)

您正在创建对象。 Factory或Builder适合您。

答案 2 :(得分:0)

虚拟构造函数设计模式可以满足您的要求。这就是它的样子......

#include <iostream>
#include <string>    
#include <vector>
using namespace std;
class Base {
    Base* b;
    // suppress the usual constructors
    Base(Base&);
    Base operator=(Base&);
protected:
    Base() { b = 0; };
public:
    virtual void Print() { b->Print(); }    
    virtual ~Base() {       
        if (b) {            
            delete b;
        }       
    }   
    Base(string type);
};
class Derived1 : public Base {
    Derived1(Derived1&);
    Derived1 operator=(Derived1&);
    Derived1() {} 
    friend class Base;
public:
    void Print() { cout << "Derived1::Print()" << endl; }
    ~Derived1() { }
};
class Derived2 : public Base {
    Derived2(Derived2&);
    Derived2 operator=(Derived2&);
    Derived2() {}
    friend class Base;
public:
    void Print() { cout << "Derived2::Print()" << endl; }   
    ~Derived2() { }
};
Base::Base(string type) {
    if (type == "Derived1")
        b = new Derived1;
    else if (type == "Derived2")
        b = new Derived2;   
}

int main() {
    vector<Base*> bases;
    cout << "virtual constructor calls:" << endl;
    bases.push_back(new Base("Derived2"));
    bases.push_back(new Base("Derived1"));
    bases.push_back(new Base("Derived1"));
    bases.push_back(new Base("Derived2"));

    for (int i = 0; i < bases.size(); i++) {
        bases[i]->Print();      
    }

    cout << "destructor calls:" << endl;
    for (int j = 0; j < bases.size(); j++) {
        delete bases[j];        
    }

    // system("pause");
    return 0;
}