I have a class ModelRecorder
with contains a reference modelRef_
to another class OpModel.
class ModelRecorder : public CompositionalModel //This is an abstract base class
{
OpModel& modelRef_;
};
When an instance of ModelRecorder
is created and modelRef_
is initalized. Thats fine I unerstand that.
How would I write a copy constructor for ModelRecorder
so that if another instance is created, the reference memeber modelRef_
will be initalized with the previous created OpModel object?
Note that CompositionalModel
is an abstract base class.
In another class there is fucntion that returns a reference to CompositionalModel
he base class. I understand returning the narrower base class is a good OOP.
For example CompositionalModel& recordedModel();
I want to pass this reference to the base class to the copy constructor.
I tried this but it gives the error, which is correct modelRef
is in the dereived class ModelRecorder
.
error: ‘const class mv::CompositionalModel’ has no member named ‘modelRef_
mv::ModelRecorder::ModelRecorder(const CompositionalModel& arg) : CompositionalModel{static_cast<const ModelRecorder&>(arg)}, modelRef_{arg.modelRef_}
{
}
A copy constructor defines what copying means,So if we pass an object only (we will be passing the copy of that object) but to create the copy we will need a copy constructor, Hence it leads to infinite recursion. So, A copy constructor must have a reference as an argument.
Passing by references ensures an actual object is passed to the copy constructor, whilst a pointer can have NULL value, and make the constructor fail.
One of the primary examples is inheritance hierarchies. And in those cases, it is fine to use const or reference member variables.
According to C++ copy constructor, we pass an object by reference to the copy function Object() { [native code] }, and we usually pass it as a const reference. One justification for passing a const reference is that it can use const wherever possible in C++ to avoid unintentionally changing objects.
There are 2 ways:
The first way - make compiler do it for you:
ModelRecorder(const ModelRecorder&) = default;
The second way - implement it yourself:
ModelRecorder(const ModelRecorder& arg)
:CompositionalModel{arg}, modelRef_{arg.modelRef_} {}
Note that you have to use the member initializer list, since we're dealing with references. The difference between the above code and this:
ModelRecorder(const ModelRecorder& arg)
:CompositionalModel{arg} {
modelRef_ = arg.modelRef_;
}
is that the later does not initialize the reference. It violates the rules, since references must be initialized, not assigned later. My best advice is to stick with the easy way, since it's the least possible to mess up using it
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With