En C #, hay un buen azúcar de sintaxis para campos con getter y setter. Además, me gustan las propiedades implementadas automáticamente que me permiten escribir
public Foo foo { get; private set; }
En C ++ tengo que escribir
private:
Foo foo;
public:
Foo getFoo() { return foo; }
¿Existe algún concepto de este tipo en C ++ 11 que me permita tener algo de sintaxis en esto?
Respuestas:
En C ++ puedes escribir tus propias características. Aquí hay una implementación de ejemplo de propiedades usando clases sin nombre. Artículo de Wikipedia
Puede escribir sus propios captadores y definidores en su lugar y si desea acceso de miembros de la clase titular, puede extender este código de ejemplo.
fuente
_alpha
para la variable privada yalpha
para la referencia.sizeof(Foo)
.C ++ no tiene esto integrado, puede definir una plantilla para imitar la funcionalidad de las propiedades:
Para definir una propiedad :
Para implementar un getter / setter personalizado, simplemente herede:
Para definir una propiedad de solo lectura :
Y para usarlo en clase
Owner
:Puede definir algunos de los anteriores en macros para hacerlo más conciso.
fuente
virtual
es probablemente innecesario para la mayoría de los casos de uso, ya que es poco probable que sea polimórfica uso de una propiedad.No hay nada en el lenguaje C ++ que funcione en todas las plataformas y compiladores.
Pero si está dispuesto a romper la compatibilidad multiplataforma y comprometerse con un compilador específico, es posible que pueda usar dicha sintaxis, por ejemplo, en Microsoft Visual C ++ , puede hacerlo
fuente
Puede emular getter y setter hasta cierto punto si tiene un miembro de tipo dedicado y anulando
operator(type)
yoperator=
para él. Si es una buena idea es otra pregunta y voy a+1
la respuesta de Kerrek SB para expresar mi opinión al respecto :)fuente
friend
al propietario del campo.Quizás eche un vistazo a la clase de propiedad que he reunido durante las últimas horas: /codereview/7786/c11-feedback-on-my-approach-to-c-like-class-properties
Te permite tener propiedades que se comporten así:
fuente
Con C ++ 11 puede definir una plantilla de clase de propiedad y usarla así:
Y aquí está la plantilla de la clase Propiedad.
fuente
C::*
significa ¿Nunca había visto algo así antes?C
. Esto es similar a un puntero de función simple, pero para llamar a la función miembro, debe proporcionar un objeto en el que se llame a la función. Esto se logra con la líneaitsObject->*itsSetter(theValue)
del ejemplo anterior. Consulte aquí para obtener una descripción más detallada de esta función.Como muchos otros ya han dicho, no hay soporte integrado en el idioma. Sin embargo, si su objetivo es el compilador de Microsoft C ++, puede aprovechar la extensión específica de Microsoft para las propiedades que se documenta aquí.
Este es el ejemplo de la página vinculada:
fuente
No, C ++ no tiene concepto de propiedades. Aunque puede ser incómodo definir y llamar a getThis () o setThat (valor), está haciendo una declaración al consumidor de esos métodos de que puede ocurrir alguna funcionalidad. Acceder a campos en C ++, por otro lado, le dice al consumidor que no ocurrirá ninguna funcionalidad adicional o inesperada. Las propiedades harían esto menos obvio ya que el acceso a la propiedad a primera vista parece reaccionar como un campo, pero de hecho reacciona como un método.
Aparte, estaba trabajando en una aplicación .NET (un CMS muy conocido) intentando crear un sistema de membresía de cliente. Debido a la forma en que habían usado las propiedades para sus objetos de usuario, se dispararon acciones que no había anticipado, lo que provocó que mis implementaciones se ejecutaran de formas extrañas, incluida la recursividad infinita. Esto se debía a que sus objetos de usuario realizaban llamadas a la capa de acceso a datos o algún sistema de almacenamiento en caché global cuando intentaban acceder a cosas simples como StreetAddress. Todo su sistema se basó en lo que yo llamaría un abuso de propiedad. Si hubieran usado métodos en lugar de propiedades, creo que me habría dado cuenta de lo que estaba fallando mucho más rápidamente. Si hubieran usado campos (o al menos hubieran hecho que sus propiedades se comportaran más como campos), creo que el sistema hubiera sido más fácil de extender y mantener.
[Editar] Cambió mis pensamientos. Había tenido un mal día y fui un poco enfadado. Esta limpieza debería ser más profesional.
fuente
Basado en https://stackoverflow.com/a/23109533/404734, aquí hay una versión con un captador público y un configurador privado:
fuente
Esto no es exactamente una propiedad, pero hace lo que quiere de la manera más sencilla:
Aquí la gran X se comporta como
public int X { get; private set; }
en la sintaxis de C #. Si desea propiedades completas, hice un primer intento para implementarlas aquí .fuente
X
del nuevo objeto seguirá apuntando al miembro del objeto antiguo, porque simplemente se copia como un miembro puntero. Esto es malo en sí mismo, pero cuando se elimina el objeto antiguo, se daña la memoria. Para que esto funcione, también tendría que implementar su propio constructor de copia, operador de asignación y constructor de movimiento.Probablemente lo sepas, pero yo simplemente haría lo siguiente:
¡Este enfoque es simple, no utiliza trucos ingeniosos y hace el trabajo!
Sin embargo, el problema es que a algunas personas no les gusta prefijar sus campos privados con un guión bajo y, por lo tanto, realmente no pueden usar este enfoque, pero afortunadamente para quienes lo hacen, es realmente sencillo. :)
Los prefijos get y set no agregan claridad a su API, pero los hacen más detallados y la razón por la que no creo que agreguen información útil es porque cuando alguien necesita usar una API si la API tiene sentido, probablemente se dará cuenta de qué prescinde de los prefijos.
Una cosa más, es fácil comprender que se trata de propiedades porque
name
no es un verbo.En el peor de los casos, si las API son coherentes y la persona no se dio cuenta de que
name()
es un acceso yname(value)
es un mutador, solo tendrá que buscarlo una vez en la documentación para comprender el patrón.Por mucho que me guste C #, ¡no creo que C ++ necesite propiedades en absoluto!
fuente
foo(bar)
(en lugar de los más lentosfoo = bar
), pero sus accesos no tienen nada que ver con las propiedades ...foo(bar)
lugar de lofoo=bar
que se puede lograr con unvoid foo(Bar bar)
método de mutador en una_foo
variable miembro.No, pero debería considerar si se trata de una función get: set y no se realiza ninguna tarea adicional dentro de los métodos get: set, simplemente hágalo público.
fuente
Recopilé las ideas de múltiples fuentes de C ++ y las puse en un ejemplo agradable, todavía bastante simple para getters / setters en C ++:
Salida:
Puede probarlo en línea aquí: http://codepad.org/zosxqjTX
fuente
¿Su clase realmente necesita hacer cumplir algún invariante o es solo una agrupación lógica de elementos miembros? Si es lo último, debería considerar convertir la cosa en una estructura y acceder a los miembros directamente.
fuente
Hay un conjunto de macros escrito aquí . Esto tiene declaraciones de propiedad convenientes para tipos de valor, tipos de referencia, tipos de solo lectura, tipos fuertes y débiles.
fuente