I was using somebody else's class which was acting odd when I pushed it into a vector. It involves a member variable which is a reference to another member variable. Here is the smallest self-contained example:
#include <iostream>
#include <vector>
class Myclass {
public:
Myclass() : a(1.0) {}
float a;
float &a_ref = a;
void addOne() {
a = a + 1.0;
}
};
int main() {
Myclass instance1;
instance1.addOne();
//prints 2:
std::cout << "instance.a_ref is " << instance1.a_ref << std::endl;
std::vector<Myclass> vec;
Myclass instance2;
vec.push_back(instance2);
vec.at(0).addOne();
//prints 1;
std::cout << "vec.at(0).a_ref is " << vec.at(0).a_ref << std::endl;
return 0;
}
I was compiling with g++
and -std=c++11
, so I didn't notice the problem for a while. I see now the issue is probably to do with the synthesised copy constructor and the reference member. But what I'm not sure about is:
g++
not give any warnings about this, using c++11 standard ?Bonus question because I'm curious:
a
or a_ref
? The problem is indeed with the defaulted copy constructor. The defaulted copy constructor initialises all members from the members of the source object. That is, the defaulted copy constructor is identical to this:
Myclass(const Myclass &src) :
a(src.a),
a_ref(src.a_ref)
{}
The defaulted copy constructor initialises all members, so it ignores any in-class initialisers.
This is also why pushing into a vector causes the problem. vec.at(0)
was created as a copy of instance2
, which means vec.at(0).a_ref
refers to instance2.a
. You could easily verify this by printing their addresses (live example).
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