如何初始化"坏"对抽象类的空引用

时间:2015-07-30 18:13:09

标签: c++ templates reference

我会直截了当地说:我有一个类模板,其中包含一个引用并更新信息:

template<class T>
class Parser {
    T& m_ref;
public:
    typedef T ValueType;
    Parser(T& ref): m_ref(ref) {}
    virtual void read(std::istream&);
};

现在,我有另一个模板创建一个新对象并使用此接口更新它,为此我有一个保存解析器的字段。 但是,我想将updater用于派生自T的类,由于Parser<Derived>不从Parser<Base>继承,因此这是不可能的。 我创建了这个解决方法,使用了一个继承自Parser<Base>但更新为Parser<Derived>的中间类:

template<class T>
struct dummy {};
template<class T>
class Creator {
    typedef shared_ptr<Parser<T> > ParserPtr;
    typedef shared_ptr<T> ValuePtr;

    ValuePtr m_output;
    ParserPtr m_parser;

    template<class ParserType>
    class LocalParser : public Parser<T> {
        ParserType m_parser;
    public:
        LocalParser(typename ParserType::ValueType& val):
            Parser<T>(/*???*/), //problems start here, I must initialize the base
            m_parser(val) {}
        void read(std::istream& is) { //use polymorphism to update into some derieved reference
            m_parser.read(is);
        }
    };
public:
    Creator(): //Uses Parser<T> as default parser
        m_output(new T), 
        m_parser(new Parser<T>(*m_output)) {}
    template<class ParserType>
    Creator(dummy<ParserType>) { //Use any parser
        auto temp = make_shared(new typename ParserType::ValueType);
        m_output = temp;
        m_parser = maked_shared(new LocalParser<ParserType>(*temp));
    }
    virtual ValuePtr read()(std::istream& is) {
        m_parser->read(is);
        return m_output;
    }
};

基本上LocalParser是一个继承自Parser<T>的中间类,但会更新来自其基础的不同引用。 这里的问题是如何初始化Parser<T>,特别是当T是抽象的时候(这是99%的时间我实际上使用派生解析器的这个类)。

我的问题归结为&#34;如何定义对(可能)使用WON的抽象类的引用?&#34; (或者是否有任何其他类型的工作,我不会定义继承自Parser<T>)的中间人。

编辑:Parser界面是我无法更改的单独代码。

1 个答案:

答案 0 :(得分:3)

您无法创建空引用。引用必须引用某些内容。这是参考和指针之间的关键差异之一。事实上,为您提供了一个可能的解决方案:

T& ref;           // error
T& ref = nullref; // no such thing

T* ptr = nullptr; // "empty" pointer!

允许使用boost::optional的另一个可能更明确的解决方案是使用{{3}}:

boost::optional<T&> opt_ref; // empty optional
opt_ref = some_t;