Exercise: Bag Of Items, By Shared Reference¶
Step 1: Transform into std::shared_ptr
¶
Continuing from Exercise: Bag Of Items, By Unique Reference, create a similar class
BagShared
that contains pointers of type std::shared_ptr<Item>
such that the tests below pass.
#include "bag-shared.h"
#include <gtest/gtest.h>
TEST(bag_shared_suite, find_by_int_ok)
{
BagShared bag;
bag.insert(std::make_shared<BagShared::Item>("something", 42));
auto item2 = std::make_shared<BagShared::Item>("anything", 666);
bag.insert(item2);
ASSERT_EQ(item2.use_count(), 2);
auto item = bag.find_by_int(42);
ASSERT_NE(item, nullptr);
ASSERT_EQ(item->first, "something");
ASSERT_EQ(item->second, 42);
}
TEST(bag_shared_suite, find_by_int_nok)
{
BagShared bag;
bag.insert(std::make_shared<BagShared::Item>("something", 42));
bag.insert(std::make_shared<BagShared::Item>("anything", 666));
auto item = bag.find_by_int(7);
ASSERT_EQ(item, nullptr);
}
TEST(bag_shared_suite, remove_by_int_ok)
{
BagShared bag;
bag.insert(std::make_shared<BagShared::Item>("something", 42));
bag.insert(std::make_shared<BagShared::Item>("anything", 666));
std::size_t nremoved = bag.remove_by_int(42);
ASSERT_EQ(nremoved, 1);
}
Did the remove_by_int()
method have to be modified?
Step 2: Accidental Move-Insert?¶
To make sure you did not accidentally leave the move-version of
insert()
from Exercise: Bag Of Items, By Unique Reference in place, make sure that the
following test passes:
#include "bag-shared.h"
#include <gtest/gtest.h>
TEST(bag_shared_suite, insert_const_ref)
{
auto p = std::make_shared<BagShared::Item>("something", 42);
BagShared bag;
bag.insert(p);
p->second = 43;
auto found = bag.find_by_int(43);
ASSERT_NE(found, nullptr);
}
Step 3: Move-Insert, And std::weak_ptr
¶
Implement a move version of insert()
that returns a
std::weak_ptr
to the inserted object, such that the following test
passes,
#include "bag-shared.h"
#include <gtest/gtest.h>
TEST(bag_shared_suite, insert_move)
{
auto p = std::make_shared<BagShared::Item>("something", 42);
BagShared bag;
auto weakref = bag.insert(std::move(p));
ASSERT_EQ(p, nullptr);
{
auto found = bag.find_by_int(42);
ASSERT_EQ(found->first, "something");
ASSERT_EQ(found->second, 42);
}
{
auto sharedref = weakref.lock();
ASSERT_NE(sharedref, nullptr);
ASSERT_EQ(sharedref->first, "something");
ASSERT_EQ(sharedref->second, 42);
}
// remove item again, and see how weak_ptr behaves
{
bag.remove_by_int(42);
auto sharedref = weakref.lock();
ASSERT_EQ(sharedref, nullptr);
}
}