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

How to initialize a "bad" empty reference to abstract class

本文关键字:bad 引用 抽象类 初始化      更新时间:2023-10-16

我将直接使用它:我有一个类模板,它包含一个引用并向其更新信息:

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

现在,我有了另一个模板,它创建了一个新对象并使用这个接口更新它,为此,我有一个保存解析器的字段。但是,我想对从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%的时间我实际使用这个类与派生解析器)。

我的问题归结为"如何定义一个引用(可能)抽象类,不会被使用?"(或者是否有其他类型的工作,我没有定义从Parser<T>继承的中间值)。

EDIT:解析器接口是一个单独的代码,我不能更改。

不能创建空引用。引用必须指向某物。这是引用和指针的主要区别之一。事实上,有一个可能的解决方案:

T& ref;           // error
T& ref = nullref; // no such thing
T* ptr = nullptr; // "empty" pointer!

另一个可能更明确的解决方案是使用boost::optional:

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