c++ - Why can't I instantiate a reference to a base class at the same time as a pointer to a derived class? -


the simplest example of question can seen in following code snippet:

class handle : public ihandle_<handle>{     public:         handle(std::unique_ptr<derived> aderived)             : derived(std::move(aderived)),               base(*aderived) {};          std::unique_ptr<derived> derived;         base& base; }; 

here, can see handle class wrapper around derived. more importantly, wish expose base class of derived, base, way of reference. reason that, ultimately, wish handle this:

class handle : public ihandle_<handle>{     private:         std::unique_ptr<derived1> myd1;         std::unique_ptr<derived2> myd2;      public:         handle(std::unique_ptr<derived1> ad1)             : myd1(std::move(ad1)),               base1(*ad1),               base2(*ad1){};         handle(std::unique_ptr<derived2> ad2)             : myd2(std::move(ad2)),               base1(*ad2),               base2(*ad2){};          base1& base1;         base2& base2;  }; 

the reason wish handle work using 'component' in 'entity component system', , i'd particular component instantiatable 2 different concrete implementations of same 2 base classes. mention because 'entity component system' design pattern definition departs traditional object-oriented programming practices: in other words, know there other ways of accomplishing trying do, wish make work in variation of have listed here.

question

why simple handle example shown in first snippet fail? compiles fine seg-faults when trying access method in base. if change order in instantiate member variables of handle, errors @ compile time think provide hints not understand going on.

here full working example of handle , classes depends on:

#include <memory> #include <iostream>  class base{     public:         base(int ax) : x(ax){};         virtual ~base() = 0;         virtual void setval(float a) = 0;         virtual float getval() = 0 ;          int x; };  base::~base(){}  class derived : public base{     public:         derived(int ax, int az)             : base(ax), z(az){};          int z; };  class concrete : public derived{     public:         concrete(int ax, int aw, int av)             : derived(ax, aw),               v(av){};         void setval(float a) override{             myval = a;         }         float getval() override{             return myval;         }         float myval;         int v; };  class ihandle{     public:         virtual ~ihandle() = 0; };  ihandle::~ihandle(){}  template <class t> class ihandle_ : public ihandle{     public:         virtual ~ihandle_() = 0; };  template <class t> ihandle_<t>::~ihandle_(){};  class handle : public ihandle_<handle>{     public:         handle(std::unique_ptr<derived> aderived)             : derived(std::move(aderived)),               base(*aderived) {};          std::unique_ptr<derived> derived;         base& base; };   int main(){     // these 2 pointers owned entitymanager     std::unique_ptr<derived> ptr(new concrete(1, 2, 3));      // can reference ihandle entitymanager     std::unique_ptr<ihandle> ahandle(new handle(std::move(ptr)));      // need, specifically, `handle` implementation of `ihandle`     handle& handle = static_cast<handle&>(*ahandle);     // seg fault on following line     handle.base.setval(10.0);     std::cout << "a = " << handle.base.getval() << std::endl;     return 0; } 

the members in c++ class initialized in order declare them, looking @ first snippet, order of initialization of members in handle class is:

  • derived
  • base

that said, means in constructor line

derived(std::move(aderived)) 

will transfer internal resources of aderived derived, reasonably resetting state of aderived. code reach statement

base(*aderived) 

base reference empty (depends on move constructor implementation inside base , derived class) object deleted memory after call of constructor itself.

so, believe reference base got in code pointing not allocated memory, giving seg_fault error.

seg_fault of time refers code using (in case writing, see setval() ) area of memory not (yet or anymore) allocated running process.

hope may help, have night, stefano


Comments

Popular posts from this blog

Is there a better way to structure post methods in Class Based Views -

performance - Why is XCHG reg, reg a 3 micro-op instruction on modern Intel architectures? -

jquery - Responsive Navbar with Sub Navbar -