1

当我尝试为这样的事情实现工厂模式时,我一遍又一遍地遇到同样的难题:

class Base {
    template <typename T>
    void doSomethingWithMember(T){
    }
    void doing(){
        doSomethingWithMember(this->a);
    }
private:
    int a;      
};
class A: public Base {
    double a;
};
class B: public Base{
    float a;
};

struct Dictionary {
    typedef Base* (*FunctionPointer)(void);
    std::map <int, FunctionPointer> fmap;

    template <typename Target>
    static Base* construct() {
        return new Target();
    }

    Dictionary() {
        fmap.insert(std::make_pair(0, &Dictionary::construct<A>));
        fmap.insert(std::make_pair(1, &Dictionary::construct<B>));
    }

    Base* Call( int i ) const {
        std::map<int, FunctionPointer>::const_iterator entry = fmap.find( i );
        return entry == fmap.end() ? new Base() : (*entry->second)();
    }
};

问题是,我无法定义aBase因为在最好的情况下它会被隐藏。但是如果没有ai 的定义,就无法为继承者实现一个函数来处理他们的a. 我还尝试将其实现Base为模板,这导致了我在通过字典创建对象时总是必须知道返回的数据类型(int、double、float)的问题——说我没有Base<int>, Base<float>,的基本对象类型Base<double>。而且我确实需要字典来给我一个对象,根据i我除了i.

4

1 回答 1

2

你制作Base模板的问题是你失去了共同的基础。但是,您可以通过使派生类成为模板来恢复它。例如:

struct Base {
    virtual ~Base() { }
};
template<typename T>
struct Derived : Base {
private:
    T a;
};

有了以上内容,您可以返回一段Base *时间让您的工厂构造Derived<X>。您的construct() 函数看起来像这样:

template<typename T>
static Base *construct() {
    return new Derived<T>();
}

任何需要操作的函数a都将被放入Derived<T>,并且因为Derived是一个模板,你只需要实现它们一次。

于 2013-05-15T16:49:03.433 回答