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.