Recently I posted a question about smart pointers. From the answers, I have tried to implement this class:
class Bar;
class Baz;
class Foo
{
public:
Foo(std::unique_ptr<Bar> param1, std::vector<std::unique_ptr<Baz>> param2);
virtual ~Foo();
// Method using myBar and myBaz polymorphically...
private:
std::unique_ptr<Bar> myBar;
std::vector<std::unique_ptr<Baz>> myBaz;
};
The constructor is implemented this way:
Foo(std::unique_ptr<Bar> param1, std::vector<std::unique_ptr<Baz>> param2):
myBar{std::move(param1)},
myBaz{std::move(param2)}
{
// Throws exception if some conditions are not met.
}
I made sure, in order to be able to use move semantics, to pass the pointers by value and to use std::move
. Both Bar
and Baz
are copyable and movable. Since I have never implemented something of the sort before, I wanted to unit test it before moving further. Using the GoogleTest framework, I wrote this test:
TEST(Foo, Constructor)
{
std::vector<std::unique_ptr<Baz>> myVec;
myVec.push_back(std::make_unique<Baz>());
myVec.push_back(std::make_unique<Baz>());
myVec.push_back(std::make_unique<Baz>());
ASSERT_NO_THROW((Foo{myVec, std::make_unique<Bar>()}));
}
Which does not compile with gcc 7.1. The error message is very nasty but seems to point out that some illegal copy happens with myVec
. As a side note, make_unique
is available on my system since I compile with the --std=c++14
flag enabled.
I decided to try something and change my test like so:
TEST(Foo, Constructor)
{
std::vector<std::unique_ptr<Baz>> myVec;
myVec.push_back(std::make_unique<Baz>());
myVec.push_back(std::make_unique<Baz>());
myVec.push_back(std::make_unique<Baz>());
ASSERT_NO_THROW((Foo{std::move(myVec), std::make_unique<Bar>()}));
}
Notice the vector is now moved into the constructor. This takes care of the copying problem and the code compiles and links fine, but then I get a segmentation fault runtime error on my test executable.
Questions:
- Why do I need to
std::move
the vector twice (once in the test, once in the initialization list) for the code to compile. Is it because the first time I move (cast) intoparam1
and then I move intomyBaz
? - What is up with the segmentation fault?
Any advice on how to do this properly is welcome of course and if you need it, I can provide the compile error gcc produced, but it is pretty cumbersome, as mentioned above.
Aucun commentaire:
Enregistrer un commentaire