Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. How to handle smart ptrs and multiple inheritance?

How to handle smart ptrs and multiple inheritance?

Scheduled Pinned Locked Moved C / C++ / MFC
questionooptutorial
5 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • U Offline
    U Offline
    User 2601640
    wrote on last edited by
    #1

    I have a class that implements two interfaces, IA and IB. Some portions of the code manipulate objects through IA pointers and other parts of the code manipulate objects through IB pointers. I would like those IA and IB clients to hold shared_ptr(ia) and shared_ptr(ib) instead of raw pointers. However, the ref count of one of the pointers could reach 0 before the other, delete the object and make the other pointer invalid. How do I practice safe use of smart ptrs of different interfaces to the same object? Thanks

    S 1 Reply Last reply
    0
    • U User 2601640

      I have a class that implements two interfaces, IA and IB. Some portions of the code manipulate objects through IA pointers and other parts of the code manipulate objects through IB pointers. I would like those IA and IB clients to hold shared_ptr(ia) and shared_ptr(ib) instead of raw pointers. However, the ref count of one of the pointers could reach 0 before the other, delete the object and make the other pointer invalid. How do I practice safe use of smart ptrs of different interfaces to the same object? Thanks

      S Offline
      S Offline
      Stuart Dootson
      wrote on last edited by
      #2

      If you use Boost shared_ptrs[^], the reference count is held on the object rather than the interface you're using - consider this code:

      #include <boost/shared_ptr.hpp>
      #include <iostream>

      class A
      {
      public:
      ~A() { std::cout << "A::~A()\n"; }
      };

      class B
      {
      public:
      ~B() { std::cout << "B::~B()\n"; }
      };

      class C : public A, public B
      {
      public:
      ~C() { std::cout << "C::~C()\n"; }
      };

      int main(int argc, char** argv)
      {
      {
      std::cout << "Enter pC\n";
      boost::shared_ptr<C> pC(new C);
      {
      std::cout << "Enter pB\n";
      boost::shared_ptr<B> pB (pC);
      std::cout << "Exit pB\n";
      }
      {
      std::cout << "Enter pA\n";
      boost::shared_ptr<A> pA (pC);
      std::cout << "Exit pA\n";
      }
      std::cout << "Exit pC\n";
      }
      }

      The output is

      Enter pC
      Enter pB
      Exit pB
      Enter pA
      Exit pA
      Exit pC
      C::~C()
      B::~B()
      A::~A()

      so, the object is only destructed once, when pC goes out of scope.

      U 1 Reply Last reply
      0
      • S Stuart Dootson

        If you use Boost shared_ptrs[^], the reference count is held on the object rather than the interface you're using - consider this code:

        #include <boost/shared_ptr.hpp>
        #include <iostream>

        class A
        {
        public:
        ~A() { std::cout << "A::~A()\n"; }
        };

        class B
        {
        public:
        ~B() { std::cout << "B::~B()\n"; }
        };

        class C : public A, public B
        {
        public:
        ~C() { std::cout << "C::~C()\n"; }
        };

        int main(int argc, char** argv)
        {
        {
        std::cout << "Enter pC\n";
        boost::shared_ptr<C> pC(new C);
        {
        std::cout << "Enter pB\n";
        boost::shared_ptr<B> pB (pC);
        std::cout << "Exit pB\n";
        }
        {
        std::cout << "Enter pA\n";
        boost::shared_ptr<A> pA (pC);
        std::cout << "Exit pA\n";
        }
        std::cout << "Exit pC\n";
        }
        }

        The output is

        Enter pC
        Enter pB
        Exit pB
        Enter pA
        Exit pA
        Exit pC
        C::~C()
        B::~B()
        A::~A()

        so, the object is only destructed once, when pC goes out of scope.

        U Offline
        U Offline
        User 2601640
        wrote on last edited by
        #3

        Thanks for the response. Unfortunately, I was not clear enough in my question. The original shared_ptr is a pointer to one of the base classes. Here is an example:

        shared_ptr<Base1> pBase1(new Derived);
        Derived* pDerived = dynamic_cast<Derived*>(pBase1.get());
        shared_ptr<Base2> pBase2(pDerived);

        This code will crash but I want to accomplish the spirit of the code: 1) Create an object. 2) Somewhere in client code, have safe access to the object in terms of a pointer to one base class. 3) Somewhere else in client code, have safe access to the object in terms of a pointer to another base class. This appears to be more of a design question than a pointer/multiple inheritance use question. Thanks

        S 1 Reply Last reply
        0
        • U User 2601640

          Thanks for the response. Unfortunately, I was not clear enough in my question. The original shared_ptr is a pointer to one of the base classes. Here is an example:

          shared_ptr<Base1> pBase1(new Derived);
          Derived* pDerived = dynamic_cast<Derived*>(pBase1.get());
          shared_ptr<Base2> pBase2(pDerived);

          This code will crash but I want to accomplish the spirit of the code: 1) Create an object. 2) Somewhere in client code, have safe access to the object in terms of a pointer to one base class. 3) Somewhere else in client code, have safe access to the object in terms of a pointer to another base class. This appears to be more of a design question than a pointer/multiple inheritance use question. Thanks

          S Offline
          S Offline
          Stuart Dootson
          wrote on last edited by
          #4

          If you're using Boost shared pointers, that's easy enough to resolve - use boost::dynamic_pointer_cast, documented on this page[^], in place of dynamic_cast. Here's some code of similar shape to yours that uses it:

          #include <iostream>
          #include <boost/shared_ptr.hpp>

          class A
          {
          public:
          virtual ~A() { std::cout << "~A\n"; }
          };

          class B
          {
          public:
          virtual ~B() { std::cout << "~B\n"; }
          };

          class C : public A, public B
          {
          public:
          virtual ~C() { std::cout << "~C\n"; }
          };

          int main(int argc, char** argv)
          {
          boost::shared_ptr<A> pA(new C);
          boost::shared_ptr<C> pC = boost::dynamic_pointer_cast<C>(pA);
          boost::shared_ptr<B> pB(pC);
          }

          U 1 Reply Last reply
          0
          • S Stuart Dootson

            If you're using Boost shared pointers, that's easy enough to resolve - use boost::dynamic_pointer_cast, documented on this page[^], in place of dynamic_cast. Here's some code of similar shape to yours that uses it:

            #include <iostream>
            #include <boost/shared_ptr.hpp>

            class A
            {
            public:
            virtual ~A() { std::cout << "~A\n"; }
            };

            class B
            {
            public:
            virtual ~B() { std::cout << "~B\n"; }
            };

            class C : public A, public B
            {
            public:
            virtual ~C() { std::cout << "~C\n"; }
            };

            int main(int argc, char** argv)
            {
            boost::shared_ptr<A> pA(new C);
            boost::shared_ptr<C> pC = boost::dynamic_pointer_cast<C>(pA);
            boost::shared_ptr<B> pB(pC);
            }

            U Offline
            U Offline
            User 2601640
            wrote on last edited by
            #5

            Thanks a bunch. That works great!

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups