Identifying an object pointer by generating and using a unique IDBit-twiddling for a custom image formatDesigning an EventHandler in C++Unique type ID, no RTTIPolymorphic (owned) reference wrapper for class hierarchiesImplementing my own signal slot mechanism using C++11Protected Pointer: a unique_ptr wrapper that auto encrypts and decrypts data in memoryC++ Parsing with chain of responsibilityFinding non-self-intersecting paths of certain moves that touch all points in a gridGraph Representation using smart pointers. Kosaraju's algorithm implementationSymbolic algebra using a generic smart pointer class

Windows 10 Programs start without visual Interface

What are these arcade games in Ghostbusters 1984?

How to make a crossed out leftrightarrow?

How can people dance around bonfires on Lag Lo'Omer - it's darchei emori?

What is the largest (size) solid object ever dropped from an airplane to impact the ground in freefall?

Logarithm of dependent variable is uniformly distributed. How to calculate a confidence interval for the mean?

Is CD audio quality good enough for the final delivery of music?

Canon 70D often overexposing or underexposing shots

Is there a general effective method to solve Smullyan style Knights and Knaves problems? Is the truth table method the most appropriate one?

Ticket sales for Queen at the Live Aid

Can't remember the name of this game

Employer demanding to see degree after poor code review

What is the most important source of natural gas? coal, oil or other?

Where did Wilson state that the US would have to force access to markets with violence?

How do you say “buy” in the sense of “believe”?

Is there a down side to setting the sampling time of a SAR ADC as long as possible?

Why does the 'metric Lagrangian' approach appear to fail in Newtonian mechanics?

Command to Search for Filenames Exceeding 143 Characters?

What is the difference between nullifying your vote and not going to vote at all?

Why do airplanes use an axial flow jet engine instead of a more compact centrifugal jet engine?

Riley Rebuses that Share a Common Theme

Placing bypass capacitors after VCC reaches the IC

Mother abusing my finances

When do characters level up?



Identifying an object pointer by generating and using a unique ID


Bit-twiddling for a custom image formatDesigning an EventHandler in C++Unique type ID, no RTTIPolymorphic (owned) reference wrapper for class hierarchiesImplementing my own signal slot mechanism using C++11Protected Pointer: a unique_ptr wrapper that auto encrypts and decrypts data in memoryC++ Parsing with chain of responsibilityFinding non-self-intersecting paths of certain moves that touch all points in a gridGraph Representation using smart pointers. Kosaraju's algorithm implementationSymbolic algebra using a generic smart pointer class






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








5












$begingroup$


I have an image class and a table class. To each image a single table can be "attached". Each <image, table> pair should be identified with an ID, which can later be used to get the pointer of image or table associated with that ID. Images in this "map" should be unique. Below is my solution, please let me know if it can be improved. Thanks.



browserInfo.h



#include <vector>
#include <tuple>

class BrowserInfo

public:
// Returns a unique ID for the <image, table> pair
/*
@param img The image file pointer
@param tbl The table view pointer
@return A unique ID for the input pair
*/
unsigned getId(image *img, table *tbl) const;

/// Returns a image pointer for the given ID
/*
@param uId The ID of <image, table> pair
@return A pointer to image file if ID exists, otherwise nullptr
*/
image *getImage(unsigned uId) const;

/// Returns a table pointer for the given ID
/*
@param uId The ID of <image, table> pair
@return A pointer to table if ID exists, otherwise nullptr
*/
table *getTable(unsigned uId) const;

private:
// alias for the type
using imageTableToId = std::tuple<image *, table *, unsigned>;

// This vector keeps track of all unique <image, table> pair IDs
mutable std::vector<imageTableToId> m_vecImageTableIds;

// The current ID
mutable unsigned m_iCurrentId = 0;

; // class BrowserInfo


browserInfo.cpp



unsigned BrowserInfo::getId(image *img, table *tbl) const

// first, try to see if we have worked with the provided image before
for (auto &tuple : m_vecImageTableIds)

if (std::get<0>(tuple) == img)

// we support a single table view for each image.
// therefore, if we find that the image is already stored
// in our vector, we just need to update the corresponding
// table pointer and return a new unique ID for this pair
std::get<1>(tuple) = tbl;
std::get<2>(tuple) = ++m_iCurrentId;

return m_iCurrentId;



// if we got here it means the image pointer wasn't stored before
// so we can just insert a new tuple into the vector
m_vecImageTableIds.push_back(std::make_tuple(img, tbl, ++m_iCurrentId));
return m_iCurrentId;


image *BrowserInfo::getImage(const unsigned uId) const

for (const auto &tuple : m_vecImageTableIds)

if (std::get<2>(tuple) == uId)
return std::get<0>(tuple);


return nullptr;


table *BrowserInfo::getTable(const unsigned uId) const

for (const auto &tuple : m_vecImageTableIds)

if (std::get<2>(tuple) == uId)
return std::get<1>(tuple);


return nullptr;










share|improve this question









$endgroup$


















    5












    $begingroup$


    I have an image class and a table class. To each image a single table can be "attached". Each <image, table> pair should be identified with an ID, which can later be used to get the pointer of image or table associated with that ID. Images in this "map" should be unique. Below is my solution, please let me know if it can be improved. Thanks.



    browserInfo.h



    #include <vector>
    #include <tuple>

    class BrowserInfo

    public:
    // Returns a unique ID for the <image, table> pair
    /*
    @param img The image file pointer
    @param tbl The table view pointer
    @return A unique ID for the input pair
    */
    unsigned getId(image *img, table *tbl) const;

    /// Returns a image pointer for the given ID
    /*
    @param uId The ID of <image, table> pair
    @return A pointer to image file if ID exists, otherwise nullptr
    */
    image *getImage(unsigned uId) const;

    /// Returns a table pointer for the given ID
    /*
    @param uId The ID of <image, table> pair
    @return A pointer to table if ID exists, otherwise nullptr
    */
    table *getTable(unsigned uId) const;

    private:
    // alias for the type
    using imageTableToId = std::tuple<image *, table *, unsigned>;

    // This vector keeps track of all unique <image, table> pair IDs
    mutable std::vector<imageTableToId> m_vecImageTableIds;

    // The current ID
    mutable unsigned m_iCurrentId = 0;

    ; // class BrowserInfo


    browserInfo.cpp



    unsigned BrowserInfo::getId(image *img, table *tbl) const

    // first, try to see if we have worked with the provided image before
    for (auto &tuple : m_vecImageTableIds)

    if (std::get<0>(tuple) == img)

    // we support a single table view for each image.
    // therefore, if we find that the image is already stored
    // in our vector, we just need to update the corresponding
    // table pointer and return a new unique ID for this pair
    std::get<1>(tuple) = tbl;
    std::get<2>(tuple) = ++m_iCurrentId;

    return m_iCurrentId;



    // if we got here it means the image pointer wasn't stored before
    // so we can just insert a new tuple into the vector
    m_vecImageTableIds.push_back(std::make_tuple(img, tbl, ++m_iCurrentId));
    return m_iCurrentId;


    image *BrowserInfo::getImage(const unsigned uId) const

    for (const auto &tuple : m_vecImageTableIds)

    if (std::get<2>(tuple) == uId)
    return std::get<0>(tuple);


    return nullptr;


    table *BrowserInfo::getTable(const unsigned uId) const

    for (const auto &tuple : m_vecImageTableIds)

    if (std::get<2>(tuple) == uId)
    return std::get<1>(tuple);


    return nullptr;










    share|improve this question









    $endgroup$














      5












      5








      5





      $begingroup$


      I have an image class and a table class. To each image a single table can be "attached". Each <image, table> pair should be identified with an ID, which can later be used to get the pointer of image or table associated with that ID. Images in this "map" should be unique. Below is my solution, please let me know if it can be improved. Thanks.



      browserInfo.h



      #include <vector>
      #include <tuple>

      class BrowserInfo

      public:
      // Returns a unique ID for the <image, table> pair
      /*
      @param img The image file pointer
      @param tbl The table view pointer
      @return A unique ID for the input pair
      */
      unsigned getId(image *img, table *tbl) const;

      /// Returns a image pointer for the given ID
      /*
      @param uId The ID of <image, table> pair
      @return A pointer to image file if ID exists, otherwise nullptr
      */
      image *getImage(unsigned uId) const;

      /// Returns a table pointer for the given ID
      /*
      @param uId The ID of <image, table> pair
      @return A pointer to table if ID exists, otherwise nullptr
      */
      table *getTable(unsigned uId) const;

      private:
      // alias for the type
      using imageTableToId = std::tuple<image *, table *, unsigned>;

      // This vector keeps track of all unique <image, table> pair IDs
      mutable std::vector<imageTableToId> m_vecImageTableIds;

      // The current ID
      mutable unsigned m_iCurrentId = 0;

      ; // class BrowserInfo


      browserInfo.cpp



      unsigned BrowserInfo::getId(image *img, table *tbl) const

      // first, try to see if we have worked with the provided image before
      for (auto &tuple : m_vecImageTableIds)

      if (std::get<0>(tuple) == img)

      // we support a single table view for each image.
      // therefore, if we find that the image is already stored
      // in our vector, we just need to update the corresponding
      // table pointer and return a new unique ID for this pair
      std::get<1>(tuple) = tbl;
      std::get<2>(tuple) = ++m_iCurrentId;

      return m_iCurrentId;



      // if we got here it means the image pointer wasn't stored before
      // so we can just insert a new tuple into the vector
      m_vecImageTableIds.push_back(std::make_tuple(img, tbl, ++m_iCurrentId));
      return m_iCurrentId;


      image *BrowserInfo::getImage(const unsigned uId) const

      for (const auto &tuple : m_vecImageTableIds)

      if (std::get<2>(tuple) == uId)
      return std::get<0>(tuple);


      return nullptr;


      table *BrowserInfo::getTable(const unsigned uId) const

      for (const auto &tuple : m_vecImageTableIds)

      if (std::get<2>(tuple) == uId)
      return std::get<1>(tuple);


      return nullptr;










      share|improve this question









      $endgroup$




      I have an image class and a table class. To each image a single table can be "attached". Each <image, table> pair should be identified with an ID, which can later be used to get the pointer of image or table associated with that ID. Images in this "map" should be unique. Below is my solution, please let me know if it can be improved. Thanks.



      browserInfo.h



      #include <vector>
      #include <tuple>

      class BrowserInfo

      public:
      // Returns a unique ID for the <image, table> pair
      /*
      @param img The image file pointer
      @param tbl The table view pointer
      @return A unique ID for the input pair
      */
      unsigned getId(image *img, table *tbl) const;

      /// Returns a image pointer for the given ID
      /*
      @param uId The ID of <image, table> pair
      @return A pointer to image file if ID exists, otherwise nullptr
      */
      image *getImage(unsigned uId) const;

      /// Returns a table pointer for the given ID
      /*
      @param uId The ID of <image, table> pair
      @return A pointer to table if ID exists, otherwise nullptr
      */
      table *getTable(unsigned uId) const;

      private:
      // alias for the type
      using imageTableToId = std::tuple<image *, table *, unsigned>;

      // This vector keeps track of all unique <image, table> pair IDs
      mutable std::vector<imageTableToId> m_vecImageTableIds;

      // The current ID
      mutable unsigned m_iCurrentId = 0;

      ; // class BrowserInfo


      browserInfo.cpp



      unsigned BrowserInfo::getId(image *img, table *tbl) const

      // first, try to see if we have worked with the provided image before
      for (auto &tuple : m_vecImageTableIds)

      if (std::get<0>(tuple) == img)

      // we support a single table view for each image.
      // therefore, if we find that the image is already stored
      // in our vector, we just need to update the corresponding
      // table pointer and return a new unique ID for this pair
      std::get<1>(tuple) = tbl;
      std::get<2>(tuple) = ++m_iCurrentId;

      return m_iCurrentId;



      // if we got here it means the image pointer wasn't stored before
      // so we can just insert a new tuple into the vector
      m_vecImageTableIds.push_back(std::make_tuple(img, tbl, ++m_iCurrentId));
      return m_iCurrentId;


      image *BrowserInfo::getImage(const unsigned uId) const

      for (const auto &tuple : m_vecImageTableIds)

      if (std::get<2>(tuple) == uId)
      return std::get<0>(tuple);


      return nullptr;


      table *BrowserInfo::getTable(const unsigned uId) const

      for (const auto &tuple : m_vecImageTableIds)

      if (std::get<2>(tuple) == uId)
      return std::get<1>(tuple);


      return nullptr;







      c++






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked 9 hours ago









      user3132457user3132457

      23917




      23917




















          2 Answers
          2






          active

          oldest

          votes


















          5












          $begingroup$

          While your solution works, it can be made even more understandable.



          Instead of using a vector of tuples, consider using an std::map:



          std::map<unsigned, std::tuple<image *, table *>> imageTablePairs;



          This is the most natural expression of the problem statement: mapping an ID to an image-table pair. It will also simplify the logic of your getId function. Here's an algorithm for what you need to do:




          Cycle through the map and check if the image exists. If it does, delete its record from the map (using std::map::erase).




          Then, simply do:



          imageTablePairs[++m_iCurrentId] = std::make_tuple(img, tbl);



          This covers both the case when the image exists (in which case its old record gets deleted per the algorithm above) and the case when the image does not exist (in which case we simply make a new record).



          For the other two getter functions, we obviously can't assume that the ID being passed in exists in the map, so we can create a private helper function that takes an ID and returns true if it exists and false otherwise. Then, the logic becomes:



          • getImage: if the ID exists, return std::get<0>(imageTablePairs[uId]).


          • getTable: if the ID exists, return std::get<1>(imageTablePairs[uId]).



          If I misunderstood the problem statement and this solution is not possible, please let me know.




          Edit: Here's the code I'd use. Tested in Visual Studio 2017 and confirmed that it compiles and runs as expected (I used empty image and table structs for testing).



          browserInfo.h



          #pragma once
          #include <map>
          #include <tuple>

          class BrowserInfo

          public:
          // Returns a unique ID for the <image, table> pair
          /*
          @param img The image file pointer
          @param tbl The table view pointer
          @return A unique ID for the input pair
          */
          unsigned getId(image *img, table *tbl) const;

          /// Returns a image pointer for the given ID
          /*
          @param uId The ID of <image, table> pair
          @return A pointer to image file if ID exists, otherwise nullptr
          */
          image *getImage(unsigned uId) const;

          /// Returns a table pointer for the given ID
          /*
          @param uId The ID of <image, table> pair
          @return A pointer to table if ID exists, otherwise nullptr
          */
          table *getTable(unsigned uId) const;

          private:

          bool idExists(unsigned uId) const;

          mutable std::map<unsigned, std::tuple<image *, table *>> imageTablePairs;

          // The current ID
          mutable unsigned m_iCurrentId = 0;

          ; // class BrowserInfo


          browserInfo.cpp



          #include "browserInfo.h"


          unsigned BrowserInfo::getId(image * img, table * tbl) const

          for (auto &record : imageTablePairs)

          if (std::get<0>(record.second) == img)

          imageTablePairs.erase(record.first);
          break;



          imageTablePairs[++m_iCurrentId] = std::make_tuple(img, tbl);
          return m_iCurrentId;


          image * BrowserInfo::getImage(unsigned uId) const

          if (idExists(uId))

          return std::get<0>(imageTablePairs[uId]);


          return nullptr;


          table * BrowserInfo::getTable(unsigned uId) const

          if (idExists(uId))

          return std::get<1>(imageTablePairs[uId]);


          return nullptr;


          bool BrowserInfo::idExists(unsigned uId) const

          std::map<unsigned, std::tuple<image*, table*>>::iterator it = imageTablePairs.find(uId);
          return it != imageTablePairs.end();







          share|improve this answer











          $endgroup$












          • $begingroup$
            this is better, thanks! i was also worried about the two members being mutable. what about that?
            $endgroup$
            – user3132457
            6 hours ago










          • $begingroup$
            It's fine, but it suggests a design flaw. The "getter" methods may need to be renamed and their const-ness revoked (if possible), because otherwise they don't really enforce it on anything.
            $endgroup$
            – AleksandrH
            6 hours ago










          • $begingroup$
            i don't feel like the constness needs to be revoked; to the user, they don't modify the class state so they need to be const
            $endgroup$
            – user3132457
            6 hours ago










          • $begingroup$
            It's up to you, but I figured the skeleton of the BrowserInfo class had been set up for you and you were filling in the .cpp, so I left that as is. The truth is that having const and mutable at the same time makes const obsolete. When applied to a method, const ensures that compilation will fail if a method is attempting to modify internal data. Mutable, on the other hand, overrides this protection. In this case, since the only data in your class is marked mutable, it doesn't make sense to have const methods. Additionally, I would consider changing the names—getters don't usually modify data.
            $endgroup$
            – AleksandrH
            4 hours ago


















          3












          $begingroup$

          As every id identifies a tuple of unique image, optional table, why over-complicate things?



          Select one alternative from here:



          1. Add a table* to image.

          2. Use a std::map or std::unordered_map from image* to table*.

          And one from here:



          1. Make the ids image*s.

          2. Add a (potentially optional) id to image. Just ensure that you can search them by id.

          3. Use a map from arbitrary id to image* (and optionally in reverse).

          Presto, you are done, and this answer will be far longer and more complicated than the solution.






          share|improve this answer









          $endgroup$













            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "196"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f221073%2fidentifying-an-object-pointer-by-generating-and-using-a-unique-id%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            5












            $begingroup$

            While your solution works, it can be made even more understandable.



            Instead of using a vector of tuples, consider using an std::map:



            std::map<unsigned, std::tuple<image *, table *>> imageTablePairs;



            This is the most natural expression of the problem statement: mapping an ID to an image-table pair. It will also simplify the logic of your getId function. Here's an algorithm for what you need to do:




            Cycle through the map and check if the image exists. If it does, delete its record from the map (using std::map::erase).




            Then, simply do:



            imageTablePairs[++m_iCurrentId] = std::make_tuple(img, tbl);



            This covers both the case when the image exists (in which case its old record gets deleted per the algorithm above) and the case when the image does not exist (in which case we simply make a new record).



            For the other two getter functions, we obviously can't assume that the ID being passed in exists in the map, so we can create a private helper function that takes an ID and returns true if it exists and false otherwise. Then, the logic becomes:



            • getImage: if the ID exists, return std::get<0>(imageTablePairs[uId]).


            • getTable: if the ID exists, return std::get<1>(imageTablePairs[uId]).



            If I misunderstood the problem statement and this solution is not possible, please let me know.




            Edit: Here's the code I'd use. Tested in Visual Studio 2017 and confirmed that it compiles and runs as expected (I used empty image and table structs for testing).



            browserInfo.h



            #pragma once
            #include <map>
            #include <tuple>

            class BrowserInfo

            public:
            // Returns a unique ID for the <image, table> pair
            /*
            @param img The image file pointer
            @param tbl The table view pointer
            @return A unique ID for the input pair
            */
            unsigned getId(image *img, table *tbl) const;

            /// Returns a image pointer for the given ID
            /*
            @param uId The ID of <image, table> pair
            @return A pointer to image file if ID exists, otherwise nullptr
            */
            image *getImage(unsigned uId) const;

            /// Returns a table pointer for the given ID
            /*
            @param uId The ID of <image, table> pair
            @return A pointer to table if ID exists, otherwise nullptr
            */
            table *getTable(unsigned uId) const;

            private:

            bool idExists(unsigned uId) const;

            mutable std::map<unsigned, std::tuple<image *, table *>> imageTablePairs;

            // The current ID
            mutable unsigned m_iCurrentId = 0;

            ; // class BrowserInfo


            browserInfo.cpp



            #include "browserInfo.h"


            unsigned BrowserInfo::getId(image * img, table * tbl) const

            for (auto &record : imageTablePairs)

            if (std::get<0>(record.second) == img)

            imageTablePairs.erase(record.first);
            break;



            imageTablePairs[++m_iCurrentId] = std::make_tuple(img, tbl);
            return m_iCurrentId;


            image * BrowserInfo::getImage(unsigned uId) const

            if (idExists(uId))

            return std::get<0>(imageTablePairs[uId]);


            return nullptr;


            table * BrowserInfo::getTable(unsigned uId) const

            if (idExists(uId))

            return std::get<1>(imageTablePairs[uId]);


            return nullptr;


            bool BrowserInfo::idExists(unsigned uId) const

            std::map<unsigned, std::tuple<image*, table*>>::iterator it = imageTablePairs.find(uId);
            return it != imageTablePairs.end();







            share|improve this answer











            $endgroup$












            • $begingroup$
              this is better, thanks! i was also worried about the two members being mutable. what about that?
              $endgroup$
              – user3132457
              6 hours ago










            • $begingroup$
              It's fine, but it suggests a design flaw. The "getter" methods may need to be renamed and their const-ness revoked (if possible), because otherwise they don't really enforce it on anything.
              $endgroup$
              – AleksandrH
              6 hours ago










            • $begingroup$
              i don't feel like the constness needs to be revoked; to the user, they don't modify the class state so they need to be const
              $endgroup$
              – user3132457
              6 hours ago










            • $begingroup$
              It's up to you, but I figured the skeleton of the BrowserInfo class had been set up for you and you were filling in the .cpp, so I left that as is. The truth is that having const and mutable at the same time makes const obsolete. When applied to a method, const ensures that compilation will fail if a method is attempting to modify internal data. Mutable, on the other hand, overrides this protection. In this case, since the only data in your class is marked mutable, it doesn't make sense to have const methods. Additionally, I would consider changing the names—getters don't usually modify data.
              $endgroup$
              – AleksandrH
              4 hours ago















            5












            $begingroup$

            While your solution works, it can be made even more understandable.



            Instead of using a vector of tuples, consider using an std::map:



            std::map<unsigned, std::tuple<image *, table *>> imageTablePairs;



            This is the most natural expression of the problem statement: mapping an ID to an image-table pair. It will also simplify the logic of your getId function. Here's an algorithm for what you need to do:




            Cycle through the map and check if the image exists. If it does, delete its record from the map (using std::map::erase).




            Then, simply do:



            imageTablePairs[++m_iCurrentId] = std::make_tuple(img, tbl);



            This covers both the case when the image exists (in which case its old record gets deleted per the algorithm above) and the case when the image does not exist (in which case we simply make a new record).



            For the other two getter functions, we obviously can't assume that the ID being passed in exists in the map, so we can create a private helper function that takes an ID and returns true if it exists and false otherwise. Then, the logic becomes:



            • getImage: if the ID exists, return std::get<0>(imageTablePairs[uId]).


            • getTable: if the ID exists, return std::get<1>(imageTablePairs[uId]).



            If I misunderstood the problem statement and this solution is not possible, please let me know.




            Edit: Here's the code I'd use. Tested in Visual Studio 2017 and confirmed that it compiles and runs as expected (I used empty image and table structs for testing).



            browserInfo.h



            #pragma once
            #include <map>
            #include <tuple>

            class BrowserInfo

            public:
            // Returns a unique ID for the <image, table> pair
            /*
            @param img The image file pointer
            @param tbl The table view pointer
            @return A unique ID for the input pair
            */
            unsigned getId(image *img, table *tbl) const;

            /// Returns a image pointer for the given ID
            /*
            @param uId The ID of <image, table> pair
            @return A pointer to image file if ID exists, otherwise nullptr
            */
            image *getImage(unsigned uId) const;

            /// Returns a table pointer for the given ID
            /*
            @param uId The ID of <image, table> pair
            @return A pointer to table if ID exists, otherwise nullptr
            */
            table *getTable(unsigned uId) const;

            private:

            bool idExists(unsigned uId) const;

            mutable std::map<unsigned, std::tuple<image *, table *>> imageTablePairs;

            // The current ID
            mutable unsigned m_iCurrentId = 0;

            ; // class BrowserInfo


            browserInfo.cpp



            #include "browserInfo.h"


            unsigned BrowserInfo::getId(image * img, table * tbl) const

            for (auto &record : imageTablePairs)

            if (std::get<0>(record.second) == img)

            imageTablePairs.erase(record.first);
            break;



            imageTablePairs[++m_iCurrentId] = std::make_tuple(img, tbl);
            return m_iCurrentId;


            image * BrowserInfo::getImage(unsigned uId) const

            if (idExists(uId))

            return std::get<0>(imageTablePairs[uId]);


            return nullptr;


            table * BrowserInfo::getTable(unsigned uId) const

            if (idExists(uId))

            return std::get<1>(imageTablePairs[uId]);


            return nullptr;


            bool BrowserInfo::idExists(unsigned uId) const

            std::map<unsigned, std::tuple<image*, table*>>::iterator it = imageTablePairs.find(uId);
            return it != imageTablePairs.end();







            share|improve this answer











            $endgroup$












            • $begingroup$
              this is better, thanks! i was also worried about the two members being mutable. what about that?
              $endgroup$
              – user3132457
              6 hours ago










            • $begingroup$
              It's fine, but it suggests a design flaw. The "getter" methods may need to be renamed and their const-ness revoked (if possible), because otherwise they don't really enforce it on anything.
              $endgroup$
              – AleksandrH
              6 hours ago










            • $begingroup$
              i don't feel like the constness needs to be revoked; to the user, they don't modify the class state so they need to be const
              $endgroup$
              – user3132457
              6 hours ago










            • $begingroup$
              It's up to you, but I figured the skeleton of the BrowserInfo class had been set up for you and you were filling in the .cpp, so I left that as is. The truth is that having const and mutable at the same time makes const obsolete. When applied to a method, const ensures that compilation will fail if a method is attempting to modify internal data. Mutable, on the other hand, overrides this protection. In this case, since the only data in your class is marked mutable, it doesn't make sense to have const methods. Additionally, I would consider changing the names—getters don't usually modify data.
              $endgroup$
              – AleksandrH
              4 hours ago













            5












            5








            5





            $begingroup$

            While your solution works, it can be made even more understandable.



            Instead of using a vector of tuples, consider using an std::map:



            std::map<unsigned, std::tuple<image *, table *>> imageTablePairs;



            This is the most natural expression of the problem statement: mapping an ID to an image-table pair. It will also simplify the logic of your getId function. Here's an algorithm for what you need to do:




            Cycle through the map and check if the image exists. If it does, delete its record from the map (using std::map::erase).




            Then, simply do:



            imageTablePairs[++m_iCurrentId] = std::make_tuple(img, tbl);



            This covers both the case when the image exists (in which case its old record gets deleted per the algorithm above) and the case when the image does not exist (in which case we simply make a new record).



            For the other two getter functions, we obviously can't assume that the ID being passed in exists in the map, so we can create a private helper function that takes an ID and returns true if it exists and false otherwise. Then, the logic becomes:



            • getImage: if the ID exists, return std::get<0>(imageTablePairs[uId]).


            • getTable: if the ID exists, return std::get<1>(imageTablePairs[uId]).



            If I misunderstood the problem statement and this solution is not possible, please let me know.




            Edit: Here's the code I'd use. Tested in Visual Studio 2017 and confirmed that it compiles and runs as expected (I used empty image and table structs for testing).



            browserInfo.h



            #pragma once
            #include <map>
            #include <tuple>

            class BrowserInfo

            public:
            // Returns a unique ID for the <image, table> pair
            /*
            @param img The image file pointer
            @param tbl The table view pointer
            @return A unique ID for the input pair
            */
            unsigned getId(image *img, table *tbl) const;

            /// Returns a image pointer for the given ID
            /*
            @param uId The ID of <image, table> pair
            @return A pointer to image file if ID exists, otherwise nullptr
            */
            image *getImage(unsigned uId) const;

            /// Returns a table pointer for the given ID
            /*
            @param uId The ID of <image, table> pair
            @return A pointer to table if ID exists, otherwise nullptr
            */
            table *getTable(unsigned uId) const;

            private:

            bool idExists(unsigned uId) const;

            mutable std::map<unsigned, std::tuple<image *, table *>> imageTablePairs;

            // The current ID
            mutable unsigned m_iCurrentId = 0;

            ; // class BrowserInfo


            browserInfo.cpp



            #include "browserInfo.h"


            unsigned BrowserInfo::getId(image * img, table * tbl) const

            for (auto &record : imageTablePairs)

            if (std::get<0>(record.second) == img)

            imageTablePairs.erase(record.first);
            break;



            imageTablePairs[++m_iCurrentId] = std::make_tuple(img, tbl);
            return m_iCurrentId;


            image * BrowserInfo::getImage(unsigned uId) const

            if (idExists(uId))

            return std::get<0>(imageTablePairs[uId]);


            return nullptr;


            table * BrowserInfo::getTable(unsigned uId) const

            if (idExists(uId))

            return std::get<1>(imageTablePairs[uId]);


            return nullptr;


            bool BrowserInfo::idExists(unsigned uId) const

            std::map<unsigned, std::tuple<image*, table*>>::iterator it = imageTablePairs.find(uId);
            return it != imageTablePairs.end();







            share|improve this answer











            $endgroup$



            While your solution works, it can be made even more understandable.



            Instead of using a vector of tuples, consider using an std::map:



            std::map<unsigned, std::tuple<image *, table *>> imageTablePairs;



            This is the most natural expression of the problem statement: mapping an ID to an image-table pair. It will also simplify the logic of your getId function. Here's an algorithm for what you need to do:




            Cycle through the map and check if the image exists. If it does, delete its record from the map (using std::map::erase).




            Then, simply do:



            imageTablePairs[++m_iCurrentId] = std::make_tuple(img, tbl);



            This covers both the case when the image exists (in which case its old record gets deleted per the algorithm above) and the case when the image does not exist (in which case we simply make a new record).



            For the other two getter functions, we obviously can't assume that the ID being passed in exists in the map, so we can create a private helper function that takes an ID and returns true if it exists and false otherwise. Then, the logic becomes:



            • getImage: if the ID exists, return std::get<0>(imageTablePairs[uId]).


            • getTable: if the ID exists, return std::get<1>(imageTablePairs[uId]).



            If I misunderstood the problem statement and this solution is not possible, please let me know.




            Edit: Here's the code I'd use. Tested in Visual Studio 2017 and confirmed that it compiles and runs as expected (I used empty image and table structs for testing).



            browserInfo.h



            #pragma once
            #include <map>
            #include <tuple>

            class BrowserInfo

            public:
            // Returns a unique ID for the <image, table> pair
            /*
            @param img The image file pointer
            @param tbl The table view pointer
            @return A unique ID for the input pair
            */
            unsigned getId(image *img, table *tbl) const;

            /// Returns a image pointer for the given ID
            /*
            @param uId The ID of <image, table> pair
            @return A pointer to image file if ID exists, otherwise nullptr
            */
            image *getImage(unsigned uId) const;

            /// Returns a table pointer for the given ID
            /*
            @param uId The ID of <image, table> pair
            @return A pointer to table if ID exists, otherwise nullptr
            */
            table *getTable(unsigned uId) const;

            private:

            bool idExists(unsigned uId) const;

            mutable std::map<unsigned, std::tuple<image *, table *>> imageTablePairs;

            // The current ID
            mutable unsigned m_iCurrentId = 0;

            ; // class BrowserInfo


            browserInfo.cpp



            #include "browserInfo.h"


            unsigned BrowserInfo::getId(image * img, table * tbl) const

            for (auto &record : imageTablePairs)

            if (std::get<0>(record.second) == img)

            imageTablePairs.erase(record.first);
            break;



            imageTablePairs[++m_iCurrentId] = std::make_tuple(img, tbl);
            return m_iCurrentId;


            image * BrowserInfo::getImage(unsigned uId) const

            if (idExists(uId))

            return std::get<0>(imageTablePairs[uId]);


            return nullptr;


            table * BrowserInfo::getTable(unsigned uId) const

            if (idExists(uId))

            return std::get<1>(imageTablePairs[uId]);


            return nullptr;


            bool BrowserInfo::idExists(unsigned uId) const

            std::map<unsigned, std::tuple<image*, table*>>::iterator it = imageTablePairs.find(uId);
            return it != imageTablePairs.end();








            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 7 hours ago

























            answered 8 hours ago









            AleksandrHAleksandrH

            33329




            33329











            • $begingroup$
              this is better, thanks! i was also worried about the two members being mutable. what about that?
              $endgroup$
              – user3132457
              6 hours ago










            • $begingroup$
              It's fine, but it suggests a design flaw. The "getter" methods may need to be renamed and their const-ness revoked (if possible), because otherwise they don't really enforce it on anything.
              $endgroup$
              – AleksandrH
              6 hours ago










            • $begingroup$
              i don't feel like the constness needs to be revoked; to the user, they don't modify the class state so they need to be const
              $endgroup$
              – user3132457
              6 hours ago










            • $begingroup$
              It's up to you, but I figured the skeleton of the BrowserInfo class had been set up for you and you were filling in the .cpp, so I left that as is. The truth is that having const and mutable at the same time makes const obsolete. When applied to a method, const ensures that compilation will fail if a method is attempting to modify internal data. Mutable, on the other hand, overrides this protection. In this case, since the only data in your class is marked mutable, it doesn't make sense to have const methods. Additionally, I would consider changing the names—getters don't usually modify data.
              $endgroup$
              – AleksandrH
              4 hours ago
















            • $begingroup$
              this is better, thanks! i was also worried about the two members being mutable. what about that?
              $endgroup$
              – user3132457
              6 hours ago










            • $begingroup$
              It's fine, but it suggests a design flaw. The "getter" methods may need to be renamed and their const-ness revoked (if possible), because otherwise they don't really enforce it on anything.
              $endgroup$
              – AleksandrH
              6 hours ago










            • $begingroup$
              i don't feel like the constness needs to be revoked; to the user, they don't modify the class state so they need to be const
              $endgroup$
              – user3132457
              6 hours ago










            • $begingroup$
              It's up to you, but I figured the skeleton of the BrowserInfo class had been set up for you and you were filling in the .cpp, so I left that as is. The truth is that having const and mutable at the same time makes const obsolete. When applied to a method, const ensures that compilation will fail if a method is attempting to modify internal data. Mutable, on the other hand, overrides this protection. In this case, since the only data in your class is marked mutable, it doesn't make sense to have const methods. Additionally, I would consider changing the names—getters don't usually modify data.
              $endgroup$
              – AleksandrH
              4 hours ago















            $begingroup$
            this is better, thanks! i was also worried about the two members being mutable. what about that?
            $endgroup$
            – user3132457
            6 hours ago




            $begingroup$
            this is better, thanks! i was also worried about the two members being mutable. what about that?
            $endgroup$
            – user3132457
            6 hours ago












            $begingroup$
            It's fine, but it suggests a design flaw. The "getter" methods may need to be renamed and their const-ness revoked (if possible), because otherwise they don't really enforce it on anything.
            $endgroup$
            – AleksandrH
            6 hours ago




            $begingroup$
            It's fine, but it suggests a design flaw. The "getter" methods may need to be renamed and their const-ness revoked (if possible), because otherwise they don't really enforce it on anything.
            $endgroup$
            – AleksandrH
            6 hours ago












            $begingroup$
            i don't feel like the constness needs to be revoked; to the user, they don't modify the class state so they need to be const
            $endgroup$
            – user3132457
            6 hours ago




            $begingroup$
            i don't feel like the constness needs to be revoked; to the user, they don't modify the class state so they need to be const
            $endgroup$
            – user3132457
            6 hours ago












            $begingroup$
            It's up to you, but I figured the skeleton of the BrowserInfo class had been set up for you and you were filling in the .cpp, so I left that as is. The truth is that having const and mutable at the same time makes const obsolete. When applied to a method, const ensures that compilation will fail if a method is attempting to modify internal data. Mutable, on the other hand, overrides this protection. In this case, since the only data in your class is marked mutable, it doesn't make sense to have const methods. Additionally, I would consider changing the names—getters don't usually modify data.
            $endgroup$
            – AleksandrH
            4 hours ago




            $begingroup$
            It's up to you, but I figured the skeleton of the BrowserInfo class had been set up for you and you were filling in the .cpp, so I left that as is. The truth is that having const and mutable at the same time makes const obsolete. When applied to a method, const ensures that compilation will fail if a method is attempting to modify internal data. Mutable, on the other hand, overrides this protection. In this case, since the only data in your class is marked mutable, it doesn't make sense to have const methods. Additionally, I would consider changing the names—getters don't usually modify data.
            $endgroup$
            – AleksandrH
            4 hours ago













            3












            $begingroup$

            As every id identifies a tuple of unique image, optional table, why over-complicate things?



            Select one alternative from here:



            1. Add a table* to image.

            2. Use a std::map or std::unordered_map from image* to table*.

            And one from here:



            1. Make the ids image*s.

            2. Add a (potentially optional) id to image. Just ensure that you can search them by id.

            3. Use a map from arbitrary id to image* (and optionally in reverse).

            Presto, you are done, and this answer will be far longer and more complicated than the solution.






            share|improve this answer









            $endgroup$

















              3












              $begingroup$

              As every id identifies a tuple of unique image, optional table, why over-complicate things?



              Select one alternative from here:



              1. Add a table* to image.

              2. Use a std::map or std::unordered_map from image* to table*.

              And one from here:



              1. Make the ids image*s.

              2. Add a (potentially optional) id to image. Just ensure that you can search them by id.

              3. Use a map from arbitrary id to image* (and optionally in reverse).

              Presto, you are done, and this answer will be far longer and more complicated than the solution.






              share|improve this answer









              $endgroup$















                3












                3








                3





                $begingroup$

                As every id identifies a tuple of unique image, optional table, why over-complicate things?



                Select one alternative from here:



                1. Add a table* to image.

                2. Use a std::map or std::unordered_map from image* to table*.

                And one from here:



                1. Make the ids image*s.

                2. Add a (potentially optional) id to image. Just ensure that you can search them by id.

                3. Use a map from arbitrary id to image* (and optionally in reverse).

                Presto, you are done, and this answer will be far longer and more complicated than the solution.






                share|improve this answer









                $endgroup$



                As every id identifies a tuple of unique image, optional table, why over-complicate things?



                Select one alternative from here:



                1. Add a table* to image.

                2. Use a std::map or std::unordered_map from image* to table*.

                And one from here:



                1. Make the ids image*s.

                2. Add a (potentially optional) id to image. Just ensure that you can search them by id.

                3. Use a map from arbitrary id to image* (and optionally in reverse).

                Presto, you are done, and this answer will be far longer and more complicated than the solution.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered 2 hours ago









                DeduplicatorDeduplicator

                12.4k2052




                12.4k2052



























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Code Review Stack Exchange!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    Use MathJax to format equations. MathJax reference.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f221073%2fidentifying-an-object-pointer-by-generating-and-using-a-unique-id%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Invision Community Contents History See also References External links Navigation menuProprietaryinvisioncommunity.comIPS Community ForumsIPS Community Forumsthis blog entry"License Changes, IP.Board 3.4, and the Future""Interview -- Matt Mecham of Ibforums""CEO Invision Power Board, Matt Mecham Is a Liar, Thief!"IPB License Explanation 1.3, 1.3.1, 2.0, and 2.1ArchivedSecurity Fixes, Updates And Enhancements For IPB 1.3.1Archived"New Demo Accounts - Invision Power Services"the original"New Default Skin"the original"Invision Power Board 3.0.0 and Applications Released"the original"Archived copy"the original"Perpetual licenses being done away with""Release Notes - Invision Power Services""Introducing: IPS Community Suite 4!"Invision Community Release Notes

                    Canceling a color specificationRandomly assigning color to Graphics3D objects?Default color for Filling in Mathematica 9Coloring specific elements of sets with a prime modified order in an array plotHow to pick a color differing significantly from the colors already in a given color list?Detection of the text colorColor numbers based on their valueCan color schemes for use with ColorData include opacity specification?My dynamic color schemes

                    Ласкавець круглолистий Зміст Опис | Поширення | Галерея | Примітки | Посилання | Навігаційне меню58171138361-22960890446Bupleurum rotundifoliumEuro+Med PlantbasePlants of the World Online — Kew ScienceGermplasm Resources Information Network (GRIN)Ласкавецькн. VI : Літери Ком — Левиправивши або дописавши її