c++ design: cast from base to derived class with no extra data members

前端 未结 2 1394
别跟我提以往
别跟我提以往 2020-12-11 03:52

I write quite a lot of code which processes message protocols. Quite often a message protocol will have a generic message frame which can be deserialised from a serial port

2条回答
  •  渐次进展
    2020-12-11 04:12

    Here is why I would not use this technique:

    1. It is a violation of the Standard and causes the behavior to be undefined. It is probably true that this works nearly all the time, but you can't rule out problems in the future. Compilers have been seen to make use of undefined behavior in optimizations, much to the disadvantage of the unsuspecting programmer. And you can't predict when and under what circumstances this will happen.

    2. You can't guarantee that neither you nor a team mate will ever add some data members to the derived type. Your class hierarchy will grow and more code will be added over time; at some point it may not be obvious to you or another programmer that adding an innocent data member to the derived type (even temporarily, perhaps for some debugging purpose) can spell disaster.

    3. There are clean and legal alternatives, for example using wrappers based on references:

      #include 
      
      struct Elem
      { };
      
      struct ElemWrapper
      {
        Elem &elem_;
      
        ElemWrapper(Elem &elem) : elem_(elem)
        { }
      };
      
      struct ElemWrapper1 : ElemWrapper
      {
        using ElemWrapper::ElemWrapper;
      
        void foo()
        { std::cout << "foo1" << std::endl; }
      };
      
      struct ElemWrapper2 : ElemWrapper
      {
        using ElemWrapper::ElemWrapper;
      
        void foo()
        { std::cout << "foo2" << std::endl; }
      };
      
      int main()
      {
        Elem e;
      
        ElemWrapper1(e).foo();
      
        return 0;
      }
      

提交回复
热议问题