new to c++. I dont know (cant find the right search terms) why the following happens.
Basically the Parent
class has a member inputs
. The Child
class has a const reference to Parent::inputs
and a Child::set_inputs()
method to alter Parent::inputs
. When I have a std::list<Child>
or std::vector<Child>
to which i iterate through and attempt to set_inputs
,
Parent::inputs
changes but Child::input
does not. Whats happening behind the scenes and how would i work my way through this? as I would need to work with lists/vectors.
class Parent {
public:
Parent() = default;
protected:
double inputs;
};
class Child : public Parent {
public:
Child() = default;
void set_inputs(const double& X) {
inputs = X;
}
public:
const double& input = inputs;
};
int main() {
using std::cout;
using std::endl;
// Without Lists, works outputs '3.0'
double X1 = 3.0;
Child test0;
test0.set_inputs(X1);
cout << test0.input << endl;
// Neither Lists or Vectors work, does not output '3.0'
Child test1, test2, test3;
std::list<Child> test_lists = { test1, test2, test3 };
for (std::list<Child>::iterator t = test_lists.begin(); t != test_lists.end(); ++t) {
t->set_inputs(X1);
cout << t->input << endl;
}
}
The default copy-ctor is establishing the reference input
from one instance to another. You're making copies of your child objects when you put them in your container. In other words, the input
members of your container copies still reference the inputs
members of you test1
, test
, etc. instances. Therefore when calling set_inputs
to change the instances Parent::inputs
member (which is happening), it has nothing to do with the inputs
that is being referenced by input
in those contained Child
objects. Note: this is also a recipe for a dangling reference just waiting in the wings, if test1
etc go out of scope before your container.
Put another way, the default copy ctor is doing this:
Child(const Child& c) : Parent(c), input(c.input) {}
Ouch. now that input
member is referencing whatever c.input
referenced; not Parent::inputs
.
To see what happens without copying change the decl you can do this: std::list<Child> test_lists(3);
. Now when you run your program it will run "correctly". There are no copies being made, therefore no mis-wires of the input
reference member.
To address this, you need to make sure that the input
member is always pinned to its parent inputs
, including on copy-ctor. In short, add this:
Child(const Child& c) : Parent(c), input(inputs) {}
to the Child
class.