diff --git a/framework/include/base/MooseObject.h b/framework/include/base/MooseObject.h index 147733b6e5fa..2f363eaeb8b2 100644 --- a/framework/include/base/MooseObject.h +++ b/framework/include/base/MooseObject.h @@ -54,6 +54,7 @@ class MooseObject : public MooseBase, * shared_from_this(). */ std::shared_ptr getSharedPtr(); + std::shared_ptr getSharedPtr() const; protected: /// Reference to the "enable" InputParameters, used by Controls for toggling on/off MooseObjects diff --git a/framework/src/base/MooseObject.C b/framework/src/base/MooseObject.C index 2a4ab57477c6..2b5ef8ff7b85 100644 --- a/framework/src/base/MooseObject.C +++ b/framework/src/base/MooseObject.C @@ -61,6 +61,13 @@ MooseObject::MooseObject(const InputParameters & parameters) "This registered object was not constructed using the Factory, which is not supported."); } +namespace +{ +const std::string not_shared_error = + "MooseObject::getSharedPtr() must only be called for objects that are managed by a " + "shared pointer. Make sure this object is build using Factory::create(...)."; +} + std::shared_ptr MooseObject::getSharedPtr() { @@ -70,7 +77,19 @@ MooseObject::getSharedPtr() } catch (std::bad_weak_ptr &) { - mooseError("MooseObject::getSharedPtr() must only be called for objects that are managed by a " - "shared pointer. Make sure this object is build using Factory::create(...)."); + mooseError(not_shared_error); + } +} + +std::shared_ptr +MooseObject::getSharedPtr() const +{ + try + { + return shared_from_this(); + } + catch (std::bad_weak_ptr &) + { + mooseError(not_shared_error); } } diff --git a/unit/src/MooseObjectTest.C b/unit/src/MooseObjectTest.C index f8d4ae7ba7bc..8fd5fdf1306b 100644 --- a/unit/src/MooseObjectTest.C +++ b/unit/src/MooseObjectTest.C @@ -11,7 +11,7 @@ #include "MooseMain.h" #include "MeshGeneratorMesh.h" -template +template void getSharedTest() { @@ -23,25 +23,34 @@ getSharedTest() std::string type = "MeshGeneratorMesh"; InputParameters params = factory->getValidParams(type); - if constexpr (shared) + if constexpr (test == 1) { auto mesh = factory->create(type, "mesh", params); // check usage EXPECT_EQ(mesh.use_count(), 1); { - auto mesh2 = mesh->getSharedPtr(); - EXPECT_EQ(mesh.use_count(), 2); + const auto mesh2 = mesh->getSharedPtr(); + const auto mesh3 = mesh2->getSharedPtr(); + EXPECT_EQ(mesh.use_count(), 3); } EXPECT_EQ(mesh.use_count(), 1); } - else + + if constexpr (test == 2) { auto mesh = factory->createUnique(type, "mesh", params); EXPECT_THROW({ auto mesh2 = mesh->getSharedPtr(); }, std::exception); } + + if constexpr (test == 3) + { + const auto mesh = factory->createUnique(type, "mesh", params); + EXPECT_THROW({ const auto mesh2 = mesh->getSharedPtr(); }, std::exception); + } } -TEST(MooseObjectTest, getSharedPtr_base) { getSharedTest(); } -TEST(MooseObjectTest, getSharedPtr_derived) { getSharedTest(); } -TEST(MooseObjectTest, getSharedPtr_error) { getSharedTest(); } +TEST(MooseObjectTest, getSharedPtr_base) { getSharedTest(); } +TEST(MooseObjectTest, getSharedPtr_derived) { getSharedTest(); } +TEST(MooseObjectTest, getSharedPtr_error) { getSharedTest(); } +TEST(MooseObjectTest, getSharedPtr_const_error) { getSharedTest(); }