代码之家  ›  专栏  ›  技术社区  ›  David Turner

重写模板类中的虚函数时出错

  •  1
  • David Turner  · 技术社区  · 7 年前

    我在重写纯虚拟函数[getContents()]时遇到问题: 我试图用派生类fpmessageImpl继承一个类fpmessage

    然而,当我尝试实例化fpmessageImpl时,编译器报告它是虚拟的,因为getContents()是一个未实现的纯虚拟函数(尽管覆盖没有问题)。这里发生了什么,有没有办法解决? clang++错误报告的最后一部分:(fpmessagingSystemImpl中有问题的代码已移至MWE中的main)

    src/fpmessagingsystemimpl.h:56:7: note: in instantiation of member function 'fp::utils::fpmessagingSystemImpl<fp::utils::fpMessagingDataStates::States>::send_message' requested here
          fpmessagingSystemImpl(std::map<MessageType,std::type_index> m) noexcept :
          ^
    src/fpengineimpl.h:19:21: note: in instantiation of member function 'fp::utils::fpmessagingSystemImpl<fp::utils::fpMessagingDataStates::States>::fpmessagingSystemImpl' requested here
          msg_sys = new fp::utils::fpmessagingSystemImpl<fp::utils::fpMessagingDataStates::States>(ds.get_map());
                        ^
    src/fpmessagingsystem.h:32:48: note: unimplemented pure virtual method 'getContents' in 'fpmessage'
          virtual std::tuple<MessageType,std::any> getContents() const noexcept = 0;
    

    可复制示例: 问题似乎在于std::make_shared如何构造新的fpmessage(主要):

    #include <memory>
    #include <any>
    #include <map>
    #include <typeindex>
    
    class fpMessagingDataStates {
    public:
      enum class States{
        INIT
      };
      const std::map<fpMessagingDataStates::States,std::type_index> get_map() {
        return m;
      }
      fpMessagingDataStates(){
        m = std::map<fpMessagingDataStates::States,std::type_index>();
        m.emplace(std::make_pair(fpMessagingDataStates::States::INIT,std::type_index(typeid(std::wstring))));
      }
    private:
      std::map<fpMessagingDataStates::States,std::type_index> m;
    };
    
    template<typename MessageType>
    class fpmessage{
    public:
      fpmessage(MessageType mt, std::any a) noexcept {};
      virtual bool validate_message (const std::map<MessageType,std::type_index>& map) const noexcept {return false;}
      virtual std::tuple<MessageType,std::any> getContents() const noexcept = 0;
      /*virtual ~fpmessage();*/
    protected:
      fpmessage() {};
    };
    
    template<typename MessageType>
    class fpmessageImpl : public fpmessage<MessageType>{
    public:
      fpmessageImpl() = delete;
      fpmessageImpl(MessageType mt, std::any a) :
        t(mt),
        contents(a) {}
      // check stored message type against a map
      virtual bool validate_message(const std::map<MessageType,std::type_index>& map) const noexcept override{
        // check the expected message type against the actual type
        auto expected_type = map.find(t);
        return (expected_type->second == std::type_index(contents.type()));
      }
      virtual std::tuple<MessageType,std::any> getContents() const noexcept override {
        return std::make_tuple(t,contents);
      }
    private:
      const MessageType t;
      const std::any contents;
    };
    
    int main(int argc, char** argv)
    {
      std::wstring s = L"Engine Started";
      auto state = fpMessagingDataStates::States::INIT;
      auto m = fpmessageImpl<fpMessagingDataStates::States>(state, s);
      auto mess = std::make_shared<fpmessage<fpMessagingDataStates::States>>(m);
      return 0;
    }
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   n. m. could be an AI    7 年前
     auto m = fpmessageImpl<fpMessagingDataStates::States>(state, s);
     auto mess = std::make_shared<fpmessage<fpMessagingDataStates::States>>(m);
    

    为了便于说明,重命名和简化:

    auto d = Derived();
    auto bp = std::make_shared<Base>(d);
    

    这是一个美化的c++11风格的包装,围绕着旧的好

     Derived d;
     Base* pb = new Base(d);
    

    第二行不会创建类型为的对象 Derived . 它将创建类型为的对象 Base 然后从 衍生 论点,在过程中切分。当然,如果 基础 是抽象的。

    为了复制 d 一个人需要

    Base* pb = new Derived(d);
    

    或者用C++11的说法

     std::shared_ptr<Base> = std::make_shared<Derived>(d);