I want to learn more about C++ and just came along a - in my eyes - very weird behavior.
Question Summary
Since the detailed explanation is a bit long, here is a summary:
I've a Container
with two member variables, of which only one can be filled with a public constructor. Both can be filled only in private. I've overloaded the copy and move for operator=
in a way that the second data member can't be filled/accessed with the. BUT when returning a container with both member variables filled and writing something like
Container containerB = Container::returnContainerWithBothMembersFilled();
containerB
has both member variables filled. This seems weird to me and that's not what I need/want.
Can someone explain to me how to solve that and why this is happening?
Detailed Explanation
In order to explain the behavior in more detail, here is a more detailed setup that reproduces my behavior:
Let's assume a class Container
with two private members dataA_
and dataB_
of type std::vector<int>
.
There exists a public constructor to initialize dataA_
(but not! dataB_
) and a private constructor to initialize both private members.
class Container {
public:
Container() = default;
Container(const Container& vector) = delete;
explicit Container(std::vector<int> data) : dataA_(std::move(data)) {}
// ...
private:
std::vector<int> dataA_;
std::vector<int> dataB_;
explicit Container(std::vector<int> dataA, std::vector<int> dataB)
: dataA_(std::move(dataA)), dataB_(std::move(dataB)) {}
};
Further, there is a function static Container func()
that returns an instance of Container
with both data members set to some value.
static Container func() {
return Container(std::vector<int>(3,1), std::vector<int>(3,2));
}
I have overloaded operator=
in 2 different variants:
Container& operator=(const Container& other)
Container& operator=(Container&& other)
where all 2 variants have the same definition shown here for the first overload exemplary:
Container& operator=(const Container& other) {
if (this != &other) {
dataA_ = other.dataA_;
}
return *this;
}
FYI: all code above is written within class Container { ... };
!
Question
Why does the following give me a container2
with a 'filled' and not empty dataB_
?
int main() {
std::cout << "init:" << std::endl;
Container container1(std::vector<int>({1, 2, 3}));
Container container2 = container1.func(); // doesnt work as expected
Container container3;
container3 = container1; // works, overloaded operator= is called and behavior is as expected
return 0;
}