una referencia punteros por pasar parametros funciones funcion declaracion como bidimensional arreglos arreglo c++ pointers map stl

c++ - referencia - punteros como parametros de funciones en c



Punteros como claves en el mapa C++ STL (5)

C ++ estándar proporciona especialización de std::less para punteros, por lo que puede usarlos de forma segura como claves de mapa, etc.

Tengo una pregunta sobre cómo se manejan los punteros a un objeto personalizado cuando se usan como claves en un mapa. Más específicamente si defino

std::map< CustomClass*, int > foo;

¿Funcionaría la implementación predeterminada de C ++ para manejar estos punteros? ¿O necesito definir una función de comparación personalizada para manejarlo? En general, ¿es una buena práctica usar punteros a los objetos como claves?


Dejando de lado la legalidad de este y cualquier posible malentendido semántico, ya mencionado, no puedo pensar en ninguna razón para usar std::map aquí en lugar de std::unordered_map . Hay intercepciones tempranas de esto en Boost y Visual C ++ si está en un compilador anterior a C ++ 11.

Dado que parece estar usando un puntero para representar un objeto único, algo como boost::flyweight podría ser aplicable.


La implementación predeterminada comparará las direcciones almacenadas por los punteros, por lo que diferentes objetos se considerarán como claves diferentes. Sin embargo, el estado lógico del objeto no será considerado. Por ejemplo, si utiliza std::string * como clave, dos objetos std::string diferentes con el mismo texto de "Hello" se considerarían una clave diferente. (Cuando se almacenan en el mapa por sus direcciones)

Está bien usar punteros como claves siempre que comprenda la diferencia importante anterior.


Los punteros se manejarán pero se compararán como punteros (orden de memoria). Tienes que pasar less functor personalizado less si deseas comparar los objetos:

template<class T> struct ptr_less { bool operator()(T* lhs, T* rhs) { return *lhs < *rhs; }}; map<Object*,int,ptr_less<Object>> mymap;


Los punteros se pueden utilizar como claves, pero especialmente con un std :: map (o std :: set). No lo aconsejaría. El comportamiento del programa no es determinista, es decir, cuando uno itera sobre el mapa, no se garantiza que el orden en el que se iteran los elementos en el mapa sea el mismo . Realmente depende de la dirección de memoria del objeto (clave). Eche un vistazo a este ejemplo, ya que puede ver, independientemente del orden de inserción en el mapa, que los elementos se repiten de forma determinista cuando la clave es una cadena en lugar de un puntero.

http://ideone.com/VKirct

#include <iostream> #include <map> using namespace std; class SomeClass { public: SomeClass(const std::string& name): m_name(name) {} std::string GetName()const {return m_name; } bool operator <(const SomeClass& rhs) const { return m_name < rhs.m_name; } private: std::string m_name; }; auto print_seq = [](const auto& seq) { for (const auto& itr: seq) {std::cout << itr.second << " , ";} std::cout << std::endl;}; int main() { // your code goes here std::map<SomeClass*, std::string> pointer_keyed_map; SomeClass s3("object3"); SomeClass s1("object1"); SomeClass s2("object2"); pointer_keyed_map.insert(std::make_pair(&s1, s1.GetName())); pointer_keyed_map.insert(std::make_pair(&s2, s2.GetName())); pointer_keyed_map.insert(std::make_pair(&s3, s3.GetName())); std::cout << "Pointer based keys: object order" << std::endl; print_seq(pointer_keyed_map); std::map<SomeClass, std::string> int_keyed_map; int_keyed_map.insert(std::make_pair(s3, s3.GetName())); int_keyed_map.insert(std::make_pair(s1, s1.GetName())); int_keyed_map.insert(std::make_pair(s2, s2.GetName())); std::cout << "String based keys: object order" << std::endl; print_seq(int_keyed_map); return 0; }