简体   繁体   中英

using 'this' pointer for two constructor

Consider this class implementation:

template <class Impl>
class LSQ {
   public:
      LSQ(O3CPU *cpu_ptr, IEW *iew_ptr);
      IEW *iewStage;
  class DcachePort : public Port
      {
         protected:
           /** Pointer to LSQ. */
           LSQ *lsq;
         public:
           DcachePort(LSQ *_lsq) 
            : Port(_lsq->name() + "-dport", _lsq->cpu), lsq(_lsq)
           { }
   };
   ...
 };

 // default code 
 template <class Impl>
 LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr)  
   :  cpu(cpu_ptr), iewStage(iew_ptr), dcachePort(this), 
 {
   ...
 }

 // default code
 template<class Impl>
 std::string
 LSQ<Impl>::name() const    
 {
    return iewStage->name() + ".lsq";   
 }

So DcachePort() takes 'this' which is actually

 LSQ(O3CPU *cpu_ptr, IEW *iew_ptr);

Now I added my own constructor:

 template <class Impl>
 class LSQ {
    public:
       LSQ(O3CPU *cpu_ptr, IEW *iew_ptr);   // default code
       LSQ(O3CPU *cpu_ptr, Fetch *f_ptr);   // added by me
       IEW *iewStage;
       Fetch *fetchStage;
   class DcachePort : public Port
       {
          protected:
            /** Pointer to LSQ. */
            LSQ *lsq;
          public:
            DcachePort(LSQ *_lsq)  // default code
             : Port(_lsq->name() + "-dport", _lsq->cpu), lsq(_lsq)
            { }
   };
   ...
  };


  // added by me
  template <class Impl>
  LSQ<Impl>::LSQ(O3CPU *cpu_ptr, Fetch *f_ptr)   // added by me
   : cpu(cpu_ptr), fetchStage(f_ptr), dcachePort(this)
  {
  }

Problem is, 'this' in my constructor is

  LSQ(O3CPU *cpu_ptr, Fetch *f_ptr)

and when it enters DcachePort(this) and then name() , it tries to execute

  return iewStage->name() + ".lsq"; 

but in my constructor, iewStage is not initialized. Instead fetchStage is used.

How can I fix that?

DcachePort has a dependency on iewStage , so if you are going to continue to use the existing DcachePort constructor implementation, you will have to pass in iewStage as a third constructor parameter.

(Or edit the existing constructor to pass in fetchStage as a third parameter.)

Alternatively, rewrite LSQ::name() so it uses information from fetchStage instead of iewStage . (and if you can't, then you'll still have to pass in iewStage as a constructor parameter`)


One final suggestion: If you can pass the "is-a" test, you could subclass LSQ , doing something like this (not sure if I have the template syntax right):

template <class Impl>
class MyLSQ : public LSQ<Impl>
{
     Fetch *fetchStage;
     MyLSQ(O3CPU *cpu_ptr, IEW *iew_ptr, Fetch *f_ptr);
}


template <class Impl>
MyLSQ<Impl>::MyLSQ(O3CPU *cpu_ptr, IEW *iew_ptr, Fetch *f_ptr)  
  : LSQ(cpu_ptr, iew_ptr), fetchStage(f_ptr)
{
}

For the "is-a" test to pass, any instance of MyLSQ has to be able to be used like an LSQ for any of LSQ's methods (including the constructor) but you can add on extra state/behavior, and override any of LSQ's virtual methods.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM