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

How far would a landing Airbus A380 go until it stops with no brakes?

Converting from CMYK to RGB (to work with it), then back to CMYK

What is the Leave No Trace way to dispose of coffee grounds?

Is it okay to have a sequel start immediately after the end of the first book?

Was planting UN flag on Moon ever discussed?

Confused with atmospheric pressure equals plastic balloon’s inner pressure

What are the unintended or dangerous consequences of allowing spells that target and damage creatures to also target and damage objects?

Is it a acceptable way to write a loss function in this form?

What would be the way to say "just saying" in German? (Not the literal translation)

Is it safe to remove python 2.7.15rc1 from Ubuntu 18.04?

NUL delimited variable

If there's something that implicates the president why is there then a national security issue? (John Dowd)

Use 1 9 6 2 in this order to make 75

Why is Na5 not played in this line of the French Defense, Advance Variation?

Grep Match and extract

What is the reason for setting flaps 1 on the ground at high temperatures?

Housemarks (superimposed & combined letters, heraldry)

Command of files and size

How and why do references in academic papers work?

Cathode rays and the cathode rays tube

How can one's career as a reviewer be ended?

Why is the length of the Kelvin unit of temperature equal to that of the Celsius unit?

Rail-to-rail op-amp only reaches 90% of VCC, works sometimes, not everytime

Do empty drive bays need to be filled?



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;








8












$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$











  • $begingroup$
    Why do you need a numeric ID here instead of modelling the relationship directly in code? Using numeric IDs for such things is virtually always a mistake (I’d call it an anti-pattern), unless you need to communicate the ID to an outside API that doesn’t know about your objects.
    $endgroup$
    – Konrad Rudolph
    May 27 at 10:49











  • $begingroup$
    basically, that's what i need. to determine these objects by the ID by an outside API.
    $endgroup$
    – user3132457
    May 27 at 11:39


















8












$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$











  • $begingroup$
    Why do you need a numeric ID here instead of modelling the relationship directly in code? Using numeric IDs for such things is virtually always a mistake (I’d call it an anti-pattern), unless you need to communicate the ID to an outside API that doesn’t know about your objects.
    $endgroup$
    – Konrad Rudolph
    May 27 at 10:49











  • $begingroup$
    basically, that's what i need. to determine these objects by the ID by an outside API.
    $endgroup$
    – user3132457
    May 27 at 11:39














8












8








8





$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 May 26 at 17:46









user3132457user3132457

25428




25428











  • $begingroup$
    Why do you need a numeric ID here instead of modelling the relationship directly in code? Using numeric IDs for such things is virtually always a mistake (I’d call it an anti-pattern), unless you need to communicate the ID to an outside API that doesn’t know about your objects.
    $endgroup$
    – Konrad Rudolph
    May 27 at 10:49











  • $begingroup$
    basically, that's what i need. to determine these objects by the ID by an outside API.
    $endgroup$
    – user3132457
    May 27 at 11:39

















  • $begingroup$
    Why do you need a numeric ID here instead of modelling the relationship directly in code? Using numeric IDs for such things is virtually always a mistake (I’d call it an anti-pattern), unless you need to communicate the ID to an outside API that doesn’t know about your objects.
    $endgroup$
    – Konrad Rudolph
    May 27 at 10:49











  • $begingroup$
    basically, that's what i need. to determine these objects by the ID by an outside API.
    $endgroup$
    – user3132457
    May 27 at 11:39
















$begingroup$
Why do you need a numeric ID here instead of modelling the relationship directly in code? Using numeric IDs for such things is virtually always a mistake (I’d call it an anti-pattern), unless you need to communicate the ID to an outside API that doesn’t know about your objects.
$endgroup$
– Konrad Rudolph
May 27 at 10:49





$begingroup$
Why do you need a numeric ID here instead of modelling the relationship directly in code? Using numeric IDs for such things is virtually always a mistake (I’d call it an anti-pattern), unless you need to communicate the ID to an outside API that doesn’t know about your objects.
$endgroup$
– Konrad Rudolph
May 27 at 10:49













$begingroup$
basically, that's what i need. to determine these objects by the ID by an outside API.
$endgroup$
– user3132457
May 27 at 11:39





$begingroup$
basically, that's what i need. to determine these objects by the ID by an outside API.
$endgroup$
– user3132457
May 27 at 11:39











2 Answers
2






active

oldest

votes


















7












$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
    May 26 at 20:19










  • $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
    May 26 at 20:30










  • $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
    May 26 at 20:45










  • $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
    May 26 at 22:27










  • $begingroup$
    another option i was thinking over is to have one method to insert and another one to get. in that case everything falls into its place.
    $endgroup$
    – user3132457
    May 27 at 3:10


















6












$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.



As an alternative, if you want multiple indices into the same collection, look at Boost.MultiIndex.






share|improve this answer











$endgroup$












  • $begingroup$
    from oop point of view, image and table are unrelated things so i can't tie them like that. hence, i achieve decoupling with the introduction of this layer between them.
    $endgroup$
    – user3132457
    May 27 at 3:04






  • 3




    $begingroup$
    @user3132457 No, they are clearly related, otherwise you wouldn’t have asked this question. OOP models code objects, not real-world objects. And the objects are related in your code’s model.
    $endgroup$
    – Konrad Rudolph
    May 27 at 10:51











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









7












$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
    May 26 at 20:19










  • $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
    May 26 at 20:30










  • $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
    May 26 at 20:45










  • $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
    May 26 at 22:27










  • $begingroup$
    another option i was thinking over is to have one method to insert and another one to get. in that case everything falls into its place.
    $endgroup$
    – user3132457
    May 27 at 3:10















7












$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
    May 26 at 20:19










  • $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
    May 26 at 20:30










  • $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
    May 26 at 20:45










  • $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
    May 26 at 22:27










  • $begingroup$
    another option i was thinking over is to have one method to insert and another one to get. in that case everything falls into its place.
    $endgroup$
    – user3132457
    May 27 at 3:10













7












7








7





$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 May 26 at 19:04

























answered May 26 at 18:37









AleksandrHAleksandrH

41839




41839











  • $begingroup$
    this is better, thanks! i was also worried about the two members being mutable. what about that?
    $endgroup$
    – user3132457
    May 26 at 20:19










  • $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
    May 26 at 20:30










  • $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
    May 26 at 20:45










  • $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
    May 26 at 22:27










  • $begingroup$
    another option i was thinking over is to have one method to insert and another one to get. in that case everything falls into its place.
    $endgroup$
    – user3132457
    May 27 at 3:10
















  • $begingroup$
    this is better, thanks! i was also worried about the two members being mutable. what about that?
    $endgroup$
    – user3132457
    May 26 at 20:19










  • $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
    May 26 at 20:30










  • $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
    May 26 at 20:45










  • $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
    May 26 at 22:27










  • $begingroup$
    another option i was thinking over is to have one method to insert and another one to get. in that case everything falls into its place.
    $endgroup$
    – user3132457
    May 27 at 3:10















$begingroup$
this is better, thanks! i was also worried about the two members being mutable. what about that?
$endgroup$
– user3132457
May 26 at 20:19




$begingroup$
this is better, thanks! i was also worried about the two members being mutable. what about that?
$endgroup$
– user3132457
May 26 at 20:19












$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
May 26 at 20:30




$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
May 26 at 20:30












$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
May 26 at 20:45




$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
May 26 at 20:45












$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
May 26 at 22:27




$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
May 26 at 22:27












$begingroup$
another option i was thinking over is to have one method to insert and another one to get. in that case everything falls into its place.
$endgroup$
– user3132457
May 27 at 3:10




$begingroup$
another option i was thinking over is to have one method to insert and another one to get. in that case everything falls into its place.
$endgroup$
– user3132457
May 27 at 3:10













6












$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.



As an alternative, if you want multiple indices into the same collection, look at Boost.MultiIndex.






share|improve this answer











$endgroup$












  • $begingroup$
    from oop point of view, image and table are unrelated things so i can't tie them like that. hence, i achieve decoupling with the introduction of this layer between them.
    $endgroup$
    – user3132457
    May 27 at 3:04






  • 3




    $begingroup$
    @user3132457 No, they are clearly related, otherwise you wouldn’t have asked this question. OOP models code objects, not real-world objects. And the objects are related in your code’s model.
    $endgroup$
    – Konrad Rudolph
    May 27 at 10:51















6












$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.



As an alternative, if you want multiple indices into the same collection, look at Boost.MultiIndex.






share|improve this answer











$endgroup$












  • $begingroup$
    from oop point of view, image and table are unrelated things so i can't tie them like that. hence, i achieve decoupling with the introduction of this layer between them.
    $endgroup$
    – user3132457
    May 27 at 3:04






  • 3




    $begingroup$
    @user3132457 No, they are clearly related, otherwise you wouldn’t have asked this question. OOP models code objects, not real-world objects. And the objects are related in your code’s model.
    $endgroup$
    – Konrad Rudolph
    May 27 at 10:51













6












6








6





$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.



As an alternative, if you want multiple indices into the same collection, look at Boost.MultiIndex.






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.



As an alternative, if you want multiple indices into the same collection, look at Boost.MultiIndex.







share|improve this answer














share|improve this answer



share|improve this answer








edited May 27 at 9:31

























answered May 27 at 0:08









DeduplicatorDeduplicator

12.7k2052




12.7k2052











  • $begingroup$
    from oop point of view, image and table are unrelated things so i can't tie them like that. hence, i achieve decoupling with the introduction of this layer between them.
    $endgroup$
    – user3132457
    May 27 at 3:04






  • 3




    $begingroup$
    @user3132457 No, they are clearly related, otherwise you wouldn’t have asked this question. OOP models code objects, not real-world objects. And the objects are related in your code’s model.
    $endgroup$
    – Konrad Rudolph
    May 27 at 10:51
















  • $begingroup$
    from oop point of view, image and table are unrelated things so i can't tie them like that. hence, i achieve decoupling with the introduction of this layer between them.
    $endgroup$
    – user3132457
    May 27 at 3:04






  • 3




    $begingroup$
    @user3132457 No, they are clearly related, otherwise you wouldn’t have asked this question. OOP models code objects, not real-world objects. And the objects are related in your code’s model.
    $endgroup$
    – Konrad Rudolph
    May 27 at 10:51















$begingroup$
from oop point of view, image and table are unrelated things so i can't tie them like that. hence, i achieve decoupling with the introduction of this layer between them.
$endgroup$
– user3132457
May 27 at 3:04




$begingroup$
from oop point of view, image and table are unrelated things so i can't tie them like that. hence, i achieve decoupling with the introduction of this layer between them.
$endgroup$
– user3132457
May 27 at 3:04




3




3




$begingroup$
@user3132457 No, they are clearly related, otherwise you wouldn’t have asked this question. OOP models code objects, not real-world objects. And the objects are related in your code’s model.
$endgroup$
– Konrad Rudolph
May 27 at 10:51




$begingroup$
@user3132457 No, they are clearly related, otherwise you wouldn’t have asked this question. OOP models code objects, not real-world objects. And the objects are related in your code’s model.
$endgroup$
– Konrad Rudolph
May 27 at 10:51

















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

Club Baloncesto Breogán Índice Historia | Pavillón | Nome | O Breogán na cultura popular | Xogadores | Adestradores | Presidentes | Palmarés | Historial | Líderes | Notas | Véxase tamén | Menú de navegacióncbbreogan.galCadroGuía oficial da ACB 2009-10, páxina 201Guía oficial ACB 1992, páxina 183. Editorial DB.É de 6.500 espectadores sentados axeitándose á última normativa"Estudiantes Junior, entre as mellores canteiras"o orixinalHemeroteca El Mundo Deportivo, 16 setembro de 1970, páxina 12Historia do BreogánAlfredo Pérez, o último canoneiroHistoria C.B. BreogánHemeroteca de El Mundo DeportivoJimmy Wright, norteamericano do Breogán deixará Lugo por ameazas de morteResultados de Breogán en 1986-87Resultados de Breogán en 1990-91Ficha de Velimir Perasović en acb.comResultados de Breogán en 1994-95Breogán arrasa al Barça. "El Mundo Deportivo", 27 de setembro de 1999, páxina 58CB Breogán - FC BarcelonaA FEB invita a participar nunha nova Liga EuropeaCharlie Bell na prensa estatalMáximos anotadores 2005Tempada 2005-06 : Tódolos Xogadores da Xornada""Non quero pensar nunha man negra, mais pregúntome que está a pasar""o orixinalRaúl López, orgulloso dos xogadores, presume da boa saúde económica do BreogánJulio González confirma que cesa como presidente del BreogánHomenaxe a Lisardo GómezA tempada do rexurdimento celesteEntrevista a Lisardo GómezEl COB dinamita el Pazo para forzar el quinto (69-73)Cafés Candelas, patrocinador del CB Breogán"Suso Lázare, novo presidente do Breogán"o orixinalCafés Candelas Breogán firma el mayor triunfo de la historiaEl Breogán realizará 17 homenajes por su cincuenta aniversario"O Breogán honra ao seu fundador e primeiro presidente"o orixinalMiguel Giao recibiu a homenaxe do PazoHomenaxe aos primeiros gladiadores celestesO home que nos amosa como ver o Breo co corazónTita Franco será homenaxeada polos #50anosdeBreoJulio Vila recibirá unha homenaxe in memoriam polos #50anosdeBreo"O Breogán homenaxeará aos seus aboados máis veteráns"Pechada ovación a «Capi» Sanmartín e Ricardo «Corazón de González»Homenaxe por décadas de informaciónPaco García volve ao Pazo con motivo do 50 aniversario"Resultados y clasificaciones""O Cafés Candelas Breogán, campión da Copa Princesa""O Cafés Candelas Breogán, equipo ACB"C.B. Breogán"Proxecto social"o orixinal"Centros asociados"o orixinalFicha en imdb.comMario Camus trata la recuperación del amor en 'La vieja música', su última película"Páxina web oficial""Club Baloncesto Breogán""C. B. Breogán S.A.D."eehttp://www.fegaba.com

Vilaño, A Laracha Índice Patrimonio | Lugares e parroquias | Véxase tamén | Menú de navegación43°14′52″N 8°36′03″O / 43.24775, -8.60070

Cegueira Índice Epidemioloxía | Deficiencia visual | Tipos de cegueira | Principais causas de cegueira | Tratamento | Técnicas de adaptación e axudas | Vida dos cegos | Primeiros auxilios | Crenzas respecto das persoas cegas | Crenzas das persoas cegas | O neno deficiente visual | Aspectos psicolóxicos da cegueira | Notas | Véxase tamén | Menú de navegación54.054.154.436928256blindnessDicionario da Real Academia GalegaPortal das Palabras"International Standards: Visual Standards — Aspects and Ranges of Vision Loss with Emphasis on Population Surveys.""Visual impairment and blindness""Presentan un plan para previr a cegueira"o orixinalACCDV Associació Catalana de Cecs i Disminuïts Visuals - PMFTrachoma"Effect of gene therapy on visual function in Leber's congenital amaurosis"1844137110.1056/NEJMoa0802268Cans guía - os mellores amigos dos cegosArquivadoEscola de cans guía para cegos en Mortágua, PortugalArquivado"Tecnología para ciegos y deficientes visuales. Recopilación de recursos gratuitos en la Red""Colorino""‘COL.diesis’, escuchar los sonidos del color""COL.diesis: Transforming Colour into Melody and Implementing the Result in a Colour Sensor Device"o orixinal"Sistema de desarrollo de sinestesia color-sonido para invidentes utilizando un protocolo de audio""Enseñanza táctil - geometría y color. Juegos didácticos para niños ciegos y videntes""Sistema Constanz"L'ocupació laboral dels cecs a l'Estat espanyol està pràcticament equiparada a la de les persones amb visió, entrevista amb Pedro ZuritaONCE (Organización Nacional de Cegos de España)Prevención da cegueiraDescrición de deficiencias visuais (Disc@pnet)Braillín, un boneco atractivo para calquera neno, con ou sen discapacidade, que permite familiarizarse co sistema de escritura e lectura brailleAxudas Técnicas36838ID00897494007150-90057129528256DOID:1432HP:0000618D001766C10.597.751.941.162C97109C0155020